diff --git a/TYPESCRIPT_FIXES_SUMMARY.md b/TYPESCRIPT_FIXES_SUMMARY.md index 757663d97..0a376d59b 100644 --- a/TYPESCRIPT_FIXES_SUMMARY.md +++ b/TYPESCRIPT_FIXES_SUMMARY.md @@ -190,7 +190,7 @@ Added pragmatic overrides for stub directories: #### Medium Priority (Database & Packages) - [ ] `src/lib/ui-pages/load-page-from-db.ts` - Implement DB page loading - [ ] `src/lib/packages/json/load-json-package.ts` - Implement JSON package loading -- [ ] `src/lib/lua/ui/generate-component-tree.ts` - Implement Lua component generation +- [ ] `src/lib/ui/generate-component-tree.ts` - Implement package component generation - [ ] `src/lib/compiler/index.ts` - Implement compilation logic #### Low Priority (GitHub & Utilities) diff --git a/TYPESCRIPT_IMPROVEMENTS_2026.md b/TYPESCRIPT_IMPROVEMENTS_2026.md index cac2a2e11..36f18dce6 100644 --- a/TYPESCRIPT_IMPROVEMENTS_2026.md +++ b/TYPESCRIPT_IMPROVEMENTS_2026.md @@ -220,7 +220,7 @@ The ESLint configuration follows a pragmatic approach with different rule severi 1. **Stub Function Implementations** (~150 TODOs) - DBAL integration functions - - Page loading from database/Lua + - Page loading from database/packages - GitHub workflow integration - Status: Documented, tracked, will be implemented when features are ready diff --git a/TYPESCRIPT_IMPROVEMENTS_SUMMARY.md b/TYPESCRIPT_IMPROVEMENTS_SUMMARY.md index 3c02e40b9..74964667e 100644 --- a/TYPESCRIPT_IMPROVEMENTS_SUMMARY.md +++ b/TYPESCRIPT_IMPROVEMENTS_SUMMARY.md @@ -204,7 +204,7 @@ Changes required: - `executePackageAction()` - Execute package-specific actions - `validateTenantAccess()` - Validate tenant access permissions - `loadPageFromDb()` - Load UI pages from database -- `loadPageFromLuaPackages()` - Load UI pages from Lua packages +- `loadPageFromPackages()` - Load UI pages from packages **Medium Priority:** - Component catalog functions (already functional, just marked TODO) @@ -288,7 +288,7 @@ Changes required: 2. **Implement page loading functions** - `loadPageFromDb()` - Database page loading - - `loadPageFromLuaPackages()` - Lua package loading + - `loadPageFromPackages()` - package loading 3. **Reduce production code warnings** - Fix `prefer-nullish-coalescing` in core files diff --git a/TYPESCRIPT_LINT_IMPROVEMENTS_SUMMARY.md b/TYPESCRIPT_LINT_IMPROVEMENTS_SUMMARY.md index 64b3b0dd4..f5f142cd4 100644 --- a/TYPESCRIPT_LINT_IMPROVEMENTS_SUMMARY.md +++ b/TYPESCRIPT_LINT_IMPROVEMENTS_SUMMARY.md @@ -209,7 +209,7 @@ High priority TODOs still to implement: #### UI Page Loaders (2 TODOs) - `lib/ui-pages/load-page-from-db.ts`: Database page loading -- `lib/ui-pages/load-page-from-lua-packages.ts`: Lua package loading +- `lib/ui-pages/load-page-from-packages.ts`: package loading #### Component System (3 TODOs) - `lib/components/component-registry.ts`: Full registry functionality @@ -274,7 +274,7 @@ High priority TODOs still to implement: ### Short Term (Next PR) 1. **Implement routing functions**: Route parsing, validation, building 2. **Fix remaining production code warnings**: ~57 warnings in non-stub files -3. **Implement UI page loaders**: Database and Lua package loading +3. **Implement UI page loaders**: Database and package loading 4. **Add component registry**: Full functionality for component system ### Long Term diff --git a/dbal/shared/api/schema/entities/core/ui_page.yaml b/dbal/shared/api/schema/entities/core/ui_page.yaml index 5c14cb33f..db7573930 100644 --- a/dbal/shared/api/schema/entities/core/ui_page.yaml +++ b/dbal/shared/api/schema/entities/core/ui_page.yaml @@ -47,7 +47,7 @@ fields: type: string optional: true nullable: true - description: "Action handlers (Lua function references)" + description: "Action handlers (script function references)" packageId: type: string diff --git a/dbal/shared/docs/CVE_ANALYSIS_2025_12.md b/dbal/shared/docs/CVE_ANALYSIS_2025_12.md index 7659903eb..5fe4425cd 100644 --- a/dbal/shared/docs/CVE_ANALYSIS_2025_12.md +++ b/dbal/shared/docs/CVE_ANALYSIS_2025_12.md @@ -1187,12 +1187,12 @@ import { createClient, RedisClientType } from 'redis' /** * Fort Knox Quota Manager - * Atomic quota operations using Redis Lua scripts +* Atomic quota operations using Redis scripts */ class AtomicQuotaManager { private redis: RedisClientType - // Lua script for atomic quota check-and-reserve + // Redis script for atomic quota check-and-reserve // Returns: 1 = success, 0 = quota exceeded, -1 = error private static readonly RESERVE_QUOTA_SCRIPT = ` local key = KEYS[1] @@ -1244,7 +1244,7 @@ class AtomicQuotaManager { private releaseScriptSha: string | null = null async initialize(): Promise { - // Pre-load Lua scripts for efficiency + // Pre-load Redis scripts for efficiency this.reserveScriptSha = await this.redis.scriptLoad( AtomicQuotaManager.RESERVE_QUOTA_SCRIPT ) diff --git a/deployment/docker/Dockerfile.cli b/deployment/docker/Dockerfile.cli deleted file mode 100644 index 6bc123c76..000000000 --- a/deployment/docker/Dockerfile.cli +++ /dev/null @@ -1,80 +0,0 @@ -# MetaBuilder CLI Dockerfile -# C++ CLI tool with DBAL client, Lua runtime, and package management -# Build: docker build -f deployment/docker/Dockerfile.cli -t metabuilder-cli . -# Run: docker run -it --rm metabuilder-cli package list - -FROM ubuntu:22.04 AS builder - -# Install build dependencies -RUN apt-get update && apt-get install -y \ - build-essential \ - cmake \ - ninja-build \ - python3 \ - python3-pip \ - git \ - curl \ - && rm -rf /var/lib/apt/lists/* - -# Install Conan 2 -RUN pip3 install --no-cache-dir conan - -# Set up Conan profile -RUN conan profile detect --force - -WORKDIR /build - -# Copy CLI source -COPY frontends/cli/ ./cli/ - -# Install dependencies with Conan -WORKDIR /build/cli -RUN conan install . \ - --output-folder build \ - --build missing \ - --settings=build_type=Release - -# Build CLI -RUN cmake -S . -B build \ - -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake - -RUN cmake --build build --config Release - -# Runtime stage - minimal image -FROM ubuntu:22.04 - -# Install runtime dependencies -RUN apt-get update && apt-get install -y \ - libcurl4 \ - ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -# Create app user -RUN useradd -m -s /bin/bash metabuilder - -WORKDIR /app - -# Copy built binary -COPY --from=builder /build/cli/build/bin/metabuilder-cli /usr/local/bin/metabuilder-cli - -# Make it executable -RUN chmod +x /usr/local/bin/metabuilder-cli - -# Copy packages directory for package operations -COPY packages/ /app/packages/ - -# Set ownership -RUN chown -R metabuilder:metabuilder /app - -USER metabuilder - -# Environment variables -ENV METABUILDER_BASE_URL=http://metabuilder-app:3000 -ENV METABUILDER_PACKAGES=/app/packages -ENV DBAL_API_URL=http://dbal-daemon:8080 - -# Default command shows help -ENTRYPOINT ["metabuilder-cli"] -CMD ["--help"] diff --git a/deployment/scripts/bootstrap-system.sh b/deployment/scripts/bootstrap-system.sh index 04362e7a1..6d5972f49 100755 --- a/deployment/scripts/bootstrap-system.sh +++ b/deployment/scripts/bootstrap-system.sh @@ -143,10 +143,10 @@ log INFO "Seeding InstalledPackage records..." # For now, use direct SQL or wait for DBAL CLI implementation # Placeholder: would call something like: -# metabuilder-cli seed --file $SEED_DIR/database/installed_packages.yaml +# TODO: Populate InstalledPackage records via seed scripts/bootstrap-system.sh log INFO "Seeding PackagePermission records..." -# metabuilder-cli seed --file $SEED_DIR/database/package_permissions.yaml +# TODO: Populate PackagePermission records via seed scripts/bootstrap-system.sh log SUCCESS "Database seeded" echo "" @@ -199,11 +199,6 @@ log INFO "Step 6/7: Verifying installation..." # Check database connectivity psql "${DATABASE_URL}" -c "SELECT COUNT(*) FROM \"InstalledPackage\";" >> "$LOG_FILE" 2>&1 || error_exit "Database verification failed" -# Check DBAL connectivity -if command -v metabuilder-cli &> /dev/null; then - metabuilder-cli package list >> "$LOG_FILE" 2>&1 || log WARN "DBAL verification failed (CLI not available)" -fi - log SUCCESS "Installation verified" echo "" diff --git a/e2e/package-rendering.spec.ts b/e2e/package-rendering.spec.ts index e6cbde525..71c1897c8 100644 --- a/e2e/package-rendering.spec.ts +++ b/e2e/package-rendering.spec.ts @@ -1,12 +1,12 @@ /** - * E2E Tests for Lua Package Rendering + * E2E Tests for Package Rendering * - * Verifies that Lua packages render correctly in the browser. - * Tests the full pipeline: JSON → Lua → React → DOM + * Verifies that packages render correctly in the browser. + * Tests the full pipeline: JSON → React → DOM */ import { expect, test } from '@playwright/test' -test.describe('Lua Package Rendering', () => { +test.describe('Package Rendering', () => { test.describe('Homepage (level1)', () => { test('should render homepage with fakemui components', async ({ page }) => { await page.goto('/') diff --git a/fakemui/CODE_REVIEW.md b/fakemui/CODE_REVIEW.md index 965a131e9..63f0056a0 100644 --- a/fakemui/CODE_REVIEW.md +++ b/fakemui/CODE_REVIEW.md @@ -297,7 +297,7 @@ color: control.enabled ? Theme.text : Theme.textDisabled From [packages/ui_level6/seed/metadata.json](packages/ui_level6/seed/metadata.json#L10): ```json "dependencies": ["ui_permissions", "ui_header", "ui_intro"], -"devDependencies": ["lua_test"] +"devDependencies": ["testing"] ``` **Assessment**: diff --git a/fakemui/fakemui/inputs/FormField.tsx b/fakemui/fakemui/inputs/FormField.tsx index 4c13c739b..428b587b5 100644 --- a/fakemui/fakemui/inputs/FormField.tsx +++ b/fakemui/fakemui/inputs/FormField.tsx @@ -13,7 +13,7 @@ export interface FormFieldProps extends React.HTMLAttributes { /** * FormField wraps form inputs with label, helper text, and error handling - * Compatible with Lua package declarative rendering + * Compatible with declarative package rendering */ export const FormField: React.FC = ({ children, diff --git a/fakemui/fakemui/surfaces/Card.tsx b/fakemui/fakemui/surfaces/Card.tsx index b55e288c3..1d2259897 100644 --- a/fakemui/fakemui/surfaces/Card.tsx +++ b/fakemui/fakemui/surfaces/Card.tsx @@ -81,7 +81,7 @@ export const CardMedia: React.FC = ({ image, alt = '', height, c /> ) -// Additional Card subcomponents for Lua package compatibility +// Additional Card subcomponents for scripted package compatibility export interface CardTitleProps extends React.HTMLAttributes { children?: React.ReactNode text?: string @@ -113,4 +113,3 @@ export const CardFooter: React.FC = ({ children, className = '' {children} ) - diff --git a/fakemui/fakemui/utils/Iframe.tsx b/fakemui/fakemui/utils/Iframe.tsx index 5c7bf496e..c95b2fa6a 100644 --- a/fakemui/fakemui/utils/Iframe.tsx +++ b/fakemui/fakemui/utils/Iframe.tsx @@ -11,7 +11,7 @@ export interface IframeProps extends React.IframeHTMLAttributes = ({ src, diff --git a/frontends/nextjs/lint.json b/frontends/nextjs/lint.json deleted file mode 100644 index 7ba1dc89c..000000000 --- a/frontends/nextjs/lint.json +++ /dev/null @@ -1,5 +0,0 @@ - -> metabuilder@0.0.0 lint -> eslint . --format=json - -[{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/eslint.config.js","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/next.config.ts","messages":[],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":87,"column":5,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":93,"endColumn":6,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .resolve on an `any` value.","line":87,"column":12,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":87,"endColumn":19,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .resolve on an `any` value.","line":89,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":89,"endColumn":24,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an `any` value.","line":98,"column":7,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":110,"endColumn":8,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .resolve on an `any` value.","line":98,"column":14,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":98,"endColumn":21,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .resolve on an `any` value.","line":100,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":100,"endColumn":26,"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":2,"message":"Unsafe return of a value of type `any`.","line":114,"column":5,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":114,"endColumn":18,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/[tenant]/[package]/[...slug]/page.tsx","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":39,"column":14,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":39,"endColumn":25},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":41,"column":14,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":41,"endColumn":25},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":52,"column":13,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":52,"endColumn":24},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":72,"column":35,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":72,"endColumn":46},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":89,"column":33,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":89,"endColumn":44},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":205,"column":22,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":205,"endColumn":24,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[5151,5153],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":206,"column":18,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":206,"endColumn":20,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[5187,5189],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":211,"column":14,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":211,"endColumn":25}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":8,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Entity Page\n * \n * Handles /{tenant}/{package}/{entity}/[...args]\n * \n * Examples:\n * /acme/forum_forge/posts -> List posts\n * /acme/forum_forge/posts/123 -> View post 123\n * /acme/forum_forge/posts/new -> Create new post\n * /acme/forum_forge/posts/123/edit -> Edit post 123\n */\n\nimport { notFound } from 'next/navigation'\n\ninterface EntityPageProps {\n params: Promise<{\n tenant: string\n package: string\n slug: string[]\n }>\n}\n\nexport default async function EntityPage({ params }: EntityPageProps) {\n const { tenant, package: pkg, slug } = await params\n\n if (tenant.length === 0 || pkg.length === 0 || slug.length === 0) {\n notFound()\n }\n\n const entity = slug[0] as string // Safe: checked slug.length > 0\n const id = slug[1]\n const action = slug[2]\n\n // Determine what view to render\n let viewType: 'list' | 'detail' | 'create' | 'edit' = 'list'\n \n if (id === 'new') {\n viewType = 'create'\n } else if (id !== null && id !== undefined && action === 'edit') {\n viewType = 'edit'\n } else if (id !== null && id !== undefined) {\n viewType = 'detail'\n }\n\n return (\n
\n
\n \n \n

{entity}

\n
\n\n
\n {viewType === 'list' && (\n \n )}\n \n {viewType === 'detail' && id !== null && id !== undefined && (\n \n )}\n \n {viewType === 'create' && (\n \n )}\n \n {viewType === 'edit' && id !== null && id !== undefined && (\n \n )}\n
\n
\n )\n}\n\n// Placeholder components - these would be replaced with actual implementations\n// that use RenderComponent with package-defined schemas\n\nfunction EntityListView({ tenant, pkg, entity }: { \n tenant: string\n pkg: string\n entity: string \n}) {\n const apiUrl = `/api/v1/${tenant}/${pkg}/${entity}`\n \n return (\n
\n
\n

{entity} List

\n \n + New {entity}\n \n
\n \n

API: {apiUrl}

\n \n {/* TODO: Fetch and render list using RenderComponent */}\n
\n Entity list will be rendered here using package schema\n
\n
\n )\n}\n\nfunction EntityDetailView({ tenant, pkg, entity, id }: { \n tenant: string\n pkg: string\n entity: string\n id: string\n}) {\n const apiUrl = `/api/v1/${tenant}/${pkg}/${entity}/${id}`\n \n return (\n
\n
\n

{entity} #{id}

\n \n
\n \n

API: {apiUrl}

\n \n {/* TODO: Fetch and render detail using RenderComponent */}\n
\n Entity detail will be rendered here using package schema\n
\n
\n )\n}\n\nfunction EntityCreateView({ tenant, pkg, entity }: { \n tenant: string\n pkg: string\n entity: string\n}) {\n const apiUrl = `/api/v1/${tenant}/${pkg}/${entity}`\n \n return (\n
\n

Create {entity}

\n \n

API: POST {apiUrl}

\n \n {/* TODO: Render create form using RenderComponent */}\n
\n Entity create form will be rendered here using package schema\n
\n
\n )\n}\n\nfunction EntityEditView({ tenant, pkg, entity, id }: { \n tenant: string\n pkg: string\n entity: string\n id: string\n}) {\n const apiUrl = `/api/v1/${tenant}/${pkg}/${entity}/${id}`\n \n return (\n
\n

Edit {entity} #{id}

\n \n

API: PUT {apiUrl}

\n \n {/* TODO: Fetch and render edit form using RenderComponent */}\n
\n Entity edit form will be rendered here using package schema\n
\n
\n )\n}\n\nexport async function generateMetadata({ params }: EntityPageProps) {\n const { tenant, package: pkg, slug } = await params\n const entity = slug?.[0] ?? 'unknown'\n const id = slug?.[1]\n \n let title = `${entity} - ${pkg}`\n if (id === 'new') {\n title = `New ${entity} - ${pkg}`\n } else if (id !== null && id !== undefined) {\n title = `${entity} #${id} - ${pkg}`\n }\n \n return {\n title: `${title} | ${tenant} | MetaBuilder`,\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/[tenant]/[package]/layout.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/[tenant]/[package]/page.tsx","messages":[],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-unused-vars","severity":2,"message":"'notFound' is defined but never used. Allowed unused vars must match /^_/u.","line":10,"column":10,"nodeType":null,"messageId":"unusedVar","endLine":10,"endColumn":18,"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/[tenant]/[package]/tenant-context.tsx","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":89,"column":11,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":89,"endColumn":22},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":90,"column":11,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":90,"endColumn":26},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":113,"column":27,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":113,"endColumn":48}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use client'\n\n/**\n * Tenant Context\n * \n * Provides tenant and package information to all components\n * within the tenant-scoped routes.\n * \n * A page has one PRIMARY package (from the URL) but may use\n * components and data from additional packages (dependencies).\n */\n\nimport { createContext, useContext, useMemo, type ReactNode } from 'react'\nimport {\n getPrefixedEntity,\n getTableName,\n} from '@/lib/routing/route-parser'\n\ninterface PackageInfo {\n id: string\n name?: string\n minLevel?: number\n /** Whether this package can own routes (true) or is dependency-only (false) */\n primary?: boolean\n}\n\ninterface TenantContextValue {\n tenant: string\n \n // Primary package (owns this route)\n primaryPackage: string\n \n // All available packages for this page (primary + dependencies)\n packages: PackageInfo[]\n \n // Legacy alias for primaryPackage\n packageId: string\n \n // Helper functions scoped to primary package\n getPrefixedEntity: (entity: string) => string\n getTableName: (entity: string) => string\n \n // Build API URL - defaults to primary package, can specify other package\n buildApiUrl: (entity: string, id?: string, action?: string, packageId?: string) => string\n \n // Check if a package is available on this page\n hasPackage: (packageId: string) => boolean\n \n // Get prefixed entity for a specific package\n getPrefixedEntityForPackage: (packageId: string, entity: string) => string\n}\n\nconst TenantContext = createContext(null)\n\ninterface TenantProviderProps {\n tenant: string\n packageId: string\n /** Additional packages available on this page (from dependencies) */\n additionalPackages?: PackageInfo[]\n children: ReactNode\n}\n\nexport function TenantProvider({ \n tenant, \n packageId, \n additionalPackages = [],\n children \n}: TenantProviderProps) {\n // Combine primary package with additional packages\n const packages = useMemo(() => {\n const primary: PackageInfo = { id: packageId }\n const all = [primary, ...additionalPackages]\n // Deduplicate by id\n return all.filter((pkg, idx) => all.findIndex(p => p.id === pkg.id) === idx)\n }, [packageId, additionalPackages])\n\n const value: TenantContextValue = useMemo(() => ({\n tenant,\n primaryPackage: packageId,\n packages,\n packageId, // Legacy alias\n \n getPrefixedEntity: (entity: string) => getPrefixedEntity(packageId, entity),\n getTableName: (entity: string) => getTableName(packageId, entity),\n \n buildApiUrl: (entity: string, id?: string, action?: string, pkg?: string) => {\n const targetPkg = pkg ?? packageId\n let url = `/api/v1/${tenant}/${targetPkg}/${entity}`\n if (id !== null && id !== undefined) url += `/${id}`\n if (action !== null && action !== undefined) url += `/${action}`\n return url\n },\n \n hasPackage: (pkgId: string) => packages.some(p => p.id === pkgId),\n \n getPrefixedEntityForPackage: (pkgId: string, entity: string) => \n getPrefixedEntity(pkgId, entity),\n }), [tenant, packageId, packages])\n\n return (\n \n {children}\n \n )\n}\n\n/**\n * Hook to access tenant context\n */\nexport function useTenant(): TenantContextValue {\n const context = useContext(TenantContext)\n \n if (context === null || context === undefined) {\n throw new Error('useTenant must be used within a TenantProvider')\n }\n \n return context\n}\n\n/**\n * Hook to check if we're in a tenant context\n */\nexport function useTenantOptional(): TenantContextValue | null {\n return useContext(TenantContext)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/_components/auth-provider.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/_components/auth-provider/auth-provider-component.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/_components/auth-provider/use-auth.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/dbal/ping/route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/dbal/schema/route.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":138,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":138,"endColumn":18},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":185,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":185,"endColumn":18}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { NextResponse } from 'next/server'\nimport * as path from 'path'\nimport * as fs from 'fs'\n\nimport {\n loadSchemaRegistry,\n saveSchemaRegistry,\n getPendingMigrations,\n generatePrismaFragment,\n approveMigration,\n rejectMigration,\n type SchemaRegistry,\n} from '@/lib/schema/schema-registry'\n\n// Use consistent path resolution\nconst getRegistryPath = () => path.join(process.cwd(), '..', '..', '..', 'prisma', 'schema-registry.json')\nconst getPrismaOutputPath = () => path.join(process.cwd(), '..', '..', '..', 'prisma', 'generated-from-packages.prisma')\n\n/**\n * GET /api/dbal/schema\n * Returns the current schema registry status\n * \n * Note: This endpoint is for admin/system use.\n * For tenant-scoped data, use /api/v1/{tenant}/{package}/{entity}\n */\nexport function GET() {\n try {\n const registryPath = getRegistryPath()\n const registry = loadSchemaRegistry(registryPath)\n const pending = getPendingMigrations(registry)\n \n return NextResponse.json({\n status: 'ok',\n packages: Object.keys(registry.packages),\n pendingMigrations: pending.length,\n migrations: pending.map(m => ({\n id: m.id,\n packageId: m.packageId,\n status: m.status,\n queuedAt: m.queuedAt,\n entities: m.entities.map(e => e.name),\n })),\n registry,\n })\n } catch (error) {\n console.error('Failed to load schema registry:', error)\n return NextResponse.json(\n { status: 'error', error: 'Failed to load schema registry' },\n { status: 500 }\n )\n }\n}\n\n/**\n * POST /api/dbal/schema\n * Schema management operations\n * Body: { action: 'scan' | 'generate' | 'approve' | 'reject', id?: string }\n */\nexport async function POST(request: Request) {\n try {\n const body = await request.json() as { action: string; id?: string }\n const { action, id } = body\n \n const registryPath = getRegistryPath()\n const registry = loadSchemaRegistry(registryPath)\n \n switch (action) {\n case 'scan':\n return handleScan(registry, registryPath)\n \n case 'generate':\n return handleGenerate(registry)\n \n case 'approve':\n return handleApprove(registry, registryPath, id)\n \n case 'reject':\n return handleReject(registry, registryPath, id)\n \n default:\n return NextResponse.json(\n { status: 'error', error: `Unknown action: ${action}` },\n { status: 400 }\n )\n }\n } catch (error) {\n console.error('Schema operation failed:', error)\n return NextResponse.json(\n { status: 'error', error: String(error) },\n { status: 500 }\n )\n }\n}\n\nfunction handleScan(registry: SchemaRegistry, registryPath: string) {\n // TODO: Import scanAllPackages when schema-scanner is implemented\n // const { scanAllPackages } = await import('@/lib/schema/schema-scanner')\n // const result = await scanAllPackages(registry)\n \n const result = { scanned: 0, queued: 0, errors: [] as string[] }\n saveSchemaRegistry(registry, registryPath)\n \n return NextResponse.json({\n status: 'ok',\n action: 'scan',\n packagesScanned: result.scanned,\n changesQueued: result.queued,\n errors: result.errors,\n })\n}\n\nfunction handleGenerate(registry: SchemaRegistry) {\n const fragment = generatePrismaFragment(registry)\n const prismaOutputPath = getPrismaOutputPath()\n \n if (fragment.trim().length === 0) {\n return NextResponse.json({\n status: 'ok',\n action: 'generate',\n message: 'No approved migrations to generate',\n generated: false,\n })\n }\n \n fs.writeFileSync(prismaOutputPath, fragment)\n \n return NextResponse.json({\n status: 'ok',\n action: 'generate',\n message: `Generated Prisma fragment at ${prismaOutputPath}`,\n generated: true,\n path: prismaOutputPath,\n nextStep: 'Run: npx prisma migrate dev --name package-schemas',\n })\n}\n\nfunction handleApprove(registry: SchemaRegistry, registryPath: string, id?: string) {\n if (id === null || id === undefined) {\n return NextResponse.json(\n { status: 'error', error: 'Migration ID required' },\n { status: 400 }\n )\n }\n \n if (id === 'all') {\n const pending = getPendingMigrations(registry)\n let approved = 0\n \n for (const migration of pending) {\n if (approveMigration(migration.id, registry)) {\n approved++\n }\n }\n \n saveSchemaRegistry(registry, registryPath)\n \n return NextResponse.json({\n status: 'ok',\n action: 'approve',\n approved,\n message: `Approved ${approved} migrations`,\n })\n }\n \n const success = approveMigration(id, registry)\n \n if (!success) {\n return NextResponse.json(\n { status: 'error', error: `Migration not found: ${id}` },\n { status: 404 }\n )\n }\n \n saveSchemaRegistry(registry, registryPath)\n \n return NextResponse.json({\n status: 'ok',\n action: 'approve',\n id,\n message: `Approved migration ${id}`,\n })\n}\n\nfunction handleReject(registry: SchemaRegistry, registryPath: string, id?: string) {\n if (id === null || id === undefined || id === '') {\n return NextResponse.json(\n { status: 'error', error: 'Migration ID required' },\n { status: 400 }\n )\n }\n \n const success = rejectMigration(id, registry)\n \n if (!success) {\n return NextResponse.json(\n { status: 'error', error: `Migration not found: ${id}` },\n { status: 404 }\n )\n }\n \n saveSchemaRegistry(registry, registryPath)\n \n return NextResponse.json({\n status: 'ok',\n action: 'reject',\n id,\n message: `Rejected migration ${id}`,\n })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/github/actions/runs/[runId]/logs/route.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":40,"column":28,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":40,"endColumn":48}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { NextRequest } from 'next/server'\nimport { NextResponse } from 'next/server'\n\nimport { createGitHubClient } from '@/lib/github/create-github-client'\nimport { fetchWorkflowRunLogs } from '@/lib/github/fetch-workflow-run-logs'\nimport { parseWorkflowRunLogsOptions } from '@/lib/github/parse-workflow-run-logs-options'\nimport { resolveGitHubRepo } from '@/lib/github/resolve-github-repo'\n\ninterface RouteParams {\n params: {\n runId: string\n }\n}\n\nexport const dynamic = 'force-dynamic'\n\nexport const GET = async (request: NextRequest, { params }: RouteParams) => {\n const runId = Number(params.runId)\n if (!Number.isFinite(runId) || runId <= 0) {\n return NextResponse.json({ error: 'Invalid run id' }, { status: 400 })\n }\n\n try {\n const { owner, repo } = resolveGitHubRepo(request.nextUrl.searchParams)\n const { runName, includeLogs, jobLimit } = parseWorkflowRunLogsOptions(\n request.nextUrl.searchParams\n )\n const client = createGitHubClient()\n\n const result = await fetchWorkflowRunLogs({\n client,\n owner,\n repo,\n runId: Math.floor(runId),\n runName,\n includeLogs,\n jobLimit,\n })\n\n if (result === null || result === undefined) {\n return NextResponse.json({ error: 'Failed to fetch workflow logs' }, { status: 500 })\n }\n\n return NextResponse.json({\n jobs: result.jobs,\n logsText: result.logsText,\n truncated: result.truncated,\n })\n } catch (error) {\n const status =\n typeof error === 'object' && error !== null && 'status' in error\n ? Number((error as { status?: number }).status)\n : 500\n const message = error instanceof Error ? error.message : 'Unknown error'\n const requiresAuth = status === 401 || status === 403\n const safeStatus = Number.isFinite(status) && status >= 400 ? status : 500\n\n return NextResponse.json({ error: message, requiresAuth }, { status: safeStatus })\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/github/actions/runs/route.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":14,"column":34,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":14,"endColumn":60}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { NextRequest } from 'next/server'\nimport { NextResponse } from 'next/server'\n\nimport { createGitHubClient } from '@/lib/github/create-github-client'\nimport { resolveGitHubRepo } from '@/lib/github/resolve-github-repo'\nimport { listWorkflowRuns } from '@/lib/github/workflows/listing/list-workflow-runs'\n\nexport const GET = async (request: NextRequest) => {\n try {\n const { owner, repo } = resolveGitHubRepo(request.nextUrl.searchParams)\n const perPageParam = request.nextUrl.searchParams.get('perPage')\n let perPage = 20\n\n if (perPageParam !== null && perPageParam !== undefined && perPageParam.length > 0) {\n const parsed = Number(perPageParam)\n if (!Number.isNaN(parsed)) {\n perPage = Math.max(1, Math.min(100, Math.floor(parsed)))\n }\n }\n\n const client = createGitHubClient()\n const runs = await listWorkflowRuns({ client, owner, repo, perPage })\n\n return NextResponse.json({\n owner,\n repo,\n runs,\n fetchedAt: new Date().toISOString(),\n hasToken: Boolean(process.env.GITHUB_TOKEN),\n })\n } catch (error) {\n const status =\n typeof error === 'object' && error !== null && 'status' in error\n ? Number((error as { status?: number }).status)\n : 500\n const message = error instanceof Error ? error.message : 'Unknown error'\n const requiresAuth = status === 401 || status === 403\n const safeStatus = Number.isFinite(status) && status >= 400 ? status : 500\n\n return NextResponse.json({ error: message, requiresAuth }, { status: safeStatus })\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/health/route.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/health/route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/packages/data/[packageId]/handlers/delete-package-data.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/packages/data/[packageId]/handlers/get-package-data.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/packages/data/[packageId]/handlers/put-package-data.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":21,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":21,"endColumn":28},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":21,"column":13,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":21,"endColumn":15,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[543,545],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":21,"column":36,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":21,"endColumn":38,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[566,568],"text":"."},"desc":"Remove unnecessary optional chain"}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { NextRequest } from 'next/server'\nimport { NextResponse } from 'next/server'\n\nimport { readJson } from '@/lib/api/read-json'\nimport { setPackageData } from '@/lib/db/packages/set-package-data'\nimport type { PackageSeedData } from '@/lib/package-types'\n\ntype PackageDataPayload = {\n data?: PackageSeedData\n}\n\ninterface RouteParams {\n params: {\n packageId: string\n }\n}\n\nexport async function PUT(request: NextRequest, { params }: RouteParams) {\n try {\n const body = await readJson(request)\n if (body?.data === null || body?.data === undefined || Array.isArray(body.data)) {\n return NextResponse.json({ error: 'Package data is required' }, { status: 400 })\n }\n\n await setPackageData(params.packageId, body.data)\n return NextResponse.json({ saved: true })\n } catch (error) {\n console.error('Error saving package data:', error)\n return NextResponse.json(\n {\n error: 'Failed to save package data',\n details: error instanceof Error ? error.message : 'Unknown error',\n },\n { status: 500 }\n )\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/packages/data/[packageId]/route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/packages/index/route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/api/v1/[...slug]/route.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":84,"column":13,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":84,"endColumn":26},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":84,"column":30,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":84,"endColumn":48},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":93,"column":35,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":93,"endColumn":56},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":128,"column":19,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":128,"endColumn":21,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[4093,4095],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":131,"column":19,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":131,"endColumn":21,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[4212,4214],"text":"."},"desc":"Remove unnecessary optional chain"}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":5,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * RESTful Multi-Tenant API Route\n * \n * Pattern: /api/v1/{tenant}/{package}/{entity}[/{id}[/{action}]]\n * \n * Examples:\n * GET /api/v1/acme/forum_forge/posts -> list posts\n * GET /api/v1/acme/forum_forge/posts/123 -> read post 123\n * POST /api/v1/acme/forum_forge/posts -> create post\n * PUT /api/v1/acme/forum_forge/posts/123 -> update post 123\n * DELETE /api/v1/acme/forum_forge/posts/123 -> delete post 123\n * POST /api/v1/acme/forum_forge/posts/123/like -> custom action\n * \n * Authentication & Authorization:\n * - Session validated from mb_session cookie\n * - Tenant access validated (user must belong to tenant or be God+)\n * - Package minLevel checked against user level\n * - Entity must be declared in package schema\n */\n\nimport type { NextRequest, NextResponse } from 'next/server'\n\nimport {\n errorResponse,\n executeDbalOperation,\n executePackageAction,\n getSessionUser,\n parseRestfulRequest,\n STATUS,\n successResponse,\n validatePackageRoute,\n validateTenantAccess,\n} from '@/lib/routing'\n\ninterface RouteParams {\n params: Promise<{ slug: string[] }>\n}\n\n/**\n * Handle all RESTful requests with full auth & DBAL execution\n */\nasync function handleRequest(\n request: NextRequest,\n { params }: RouteParams\n): Promise {\n const resolvedParams = await params\n \n // 1. Parse the route\n const context = parseRestfulRequest(request, resolvedParams)\n if ('error' in context) {\n return errorResponse(context.error, context.status)\n }\n\n const { route, operation, dbalOp } = context\n\n // 2. Get current user session (may be null for public routes)\n const { user } = await getSessionUser()\n \n // 3. Validate package exists and user has required level\n const packageResult = validatePackageRoute(route.package, route.entity, user)\n if (packageResult.allowed === false) {\n const status = user === null ? STATUS.UNAUTHORIZED : STATUS.FORBIDDEN\n return errorResponse(packageResult.reason ?? 'Access denied', status)\n }\n\n // 4. Validate tenant access\n const tenantResult = await validateTenantAccess(\n user,\n route.tenant,\n packageResult.package?.minLevel ?? 1\n )\n if (tenantResult.allowed === false) {\n const status = user === null ? STATUS.UNAUTHORIZED : STATUS.FORBIDDEN\n return errorResponse(tenantResult.reason ?? 'Access denied', status)\n }\n\n // 5. Execute the DBAL operation\n try {\n // Parse request body for mutations\n let body: Record | undefined\n if (['POST', 'PUT', 'PATCH'].includes(request.method)) {\n try {\n const text = await request.text()\n if (text !== null && text !== undefined && text !== '') {\n body = JSON.parse(text) as Record\n }\n } catch {\n return errorResponse('Invalid JSON body', STATUS.BAD_REQUEST)\n }\n }\n\n // Handle custom actions separately\n if (operation === 'action' && route.action !== null && route.action !== undefined) {\n if (tenantResult.tenant === null || tenantResult.tenant === undefined) {\n return errorResponse('Tenant not found', STATUS.NOT_FOUND)\n }\n\n const actionResult = await executePackageAction(\n route.package,\n route.entity,\n route.action,\n route.id ?? null,\n { user, tenant: tenantResult.tenant, body }\n )\n \n if (actionResult.success === false) {\n return errorResponse(actionResult.error ?? 'Action failed', STATUS.BAD_REQUEST)\n }\n \n return successResponse(actionResult.data, STATUS.OK)\n }\n\n // Ensure tenant is available for CRUD operations\n if (tenantResult.tenant === null || tenantResult.tenant === undefined) {\n return errorResponse('Tenant not found', STATUS.NOT_FOUND)\n }\n\n // Execute standard CRUD operation\n const result = await executeDbalOperation(dbalOp, {\n user,\n tenant: tenantResult.tenant,\n body,\n })\n\n if (!result.success) {\n // Map common errors to appropriate status codes\n const errorMsg = result.error ?? 'Operation failed'\n if (errorMsg?.includes('not found') === true) {\n return errorResponse(errorMsg, STATUS.NOT_FOUND)\n }\n if (errorMsg?.includes('required') === true) {\n return errorResponse(errorMsg, STATUS.BAD_REQUEST)\n }\n return errorResponse(errorMsg, STATUS.INTERNAL_ERROR)\n }\n\n // Build response with metadata\n const responseData = result.meta !== null && result.meta !== undefined\n ? { data: result.data, ...(result.meta as Record) }\n : result.data\n\n // Map operation to appropriate status code\n switch (operation) {\n case 'create':\n return successResponse(responseData, STATUS.CREATED)\n case 'delete':\n return successResponse(responseData, STATUS.OK)\n default:\n return successResponse(responseData, STATUS.OK)\n }\n } catch (error) {\n console.error('DBAL operation failed:', error)\n return errorResponse(\n error instanceof Error ? error.message : 'Operation failed',\n STATUS.INTERNAL_ERROR\n )\n }\n}\n\nexport async function GET(request: NextRequest, params: RouteParams) {\n return handleRequest(request, params)\n}\n\nexport async function POST(request: NextRequest, params: RouteParams) {\n return handleRequest(request, params)\n}\n\nexport async function PUT(request: NextRequest, params: RouteParams) {\n return handleRequest(request, params)\n}\n\nexport async function PATCH(request: NextRequest, params: RouteParams) {\n return handleRequest(request, params)\n}\n\nexport async function DELETE(request: NextRequest, params: RouteParams) {\n return handleRequest(request, params)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/dbal-daemon/page.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/layout.tsx","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":72,"column":10,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":72,"endColumn":34},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":80,"column":10,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":80,"endColumn":34}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import '@/main.scss'\n\nimport type { Metadata, Viewport } from 'next'\n\nimport { PackageStyleLoader } from '@/components/PackageStyleLoader'\nimport { Providers } from './providers'\nimport { loadPackage } from '@/lib/packages/unified'\n\n// List of packages to load styles from\nconst PACKAGES_WITH_STYLES = [\n 'shared',\n 'ui_home',\n 'ui_header',\n 'ui_footer',\n 'ui_level2',\n 'ui_level3',\n 'ui_level4',\n 'ui_level5',\n 'ui_level6',\n 'admin_panel',\n 'code_editor',\n 'css_designer',\n]\n\nexport const metadata: Metadata = {\n title: {\n default: 'MetaBuilder - Data-Driven Application Platform',\n template: '%s | MetaBuilder',\n },\n description:\n 'A data-driven, multi-tenant application platform where 95% of functionality is defined through JSON and Lua.',\n keywords: ['metabuilder', 'low-code', 'no-code', 'lua', 'platform', 'multi-tenant'],\n authors: [{ name: 'MetaBuilder Team' }],\n creator: 'MetaBuilder',\n icons: {\n icon: '/favicon.ico',\n },\n manifest: '/manifest.json',\n}\n\nexport const viewport: Viewport = {\n width: 'device-width',\n initialScale: 1,\n themeColor: [\n { media: '(prefers-color-scheme: light)', color: '#ffffff' },\n { media: '(prefers-color-scheme: dark)', color: '#0a0a0a' },\n ],\n}\n\nexport default async function RootLayout({ children }: { children: React.ReactNode }) {\n // Load header/footer packages using unified loader\n const headerPkg = await loadPackage('ui_header')\n const footerPkg = await loadPackage('ui_footer')\n\n const headerName = headerPkg?.name ?? null\n const footerName = footerPkg?.name ?? null\n\n return (\n \n \n \n \n \n \n \n \n\n {/* Render a simple header/footer when package metadata is available */}\n {headerName !== undefined && headerName !== null && headerName.length > 0 ? (\n
{headerName}
\n ) : null}\n\n \n {children}\n \n\n {footerName !== undefined && footerName !== null && footerName.length > 0 ? (\n
{footerName}
\n ) : null}\n \n \n )\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/levels/levels-data.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/page.tsx","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":55,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":55,"endColumn":37},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":55,"column":41,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":55,"endColumn":74},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":61,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":61,"endColumn":38},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":61,"column":42,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":61,"endColumn":66},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":61,"column":70,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":61,"endColumn":99},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":61,"column":103,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":61,"endColumn":127},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":63,"column":28,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":63,"endColumn":30,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[2709,2711],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":65,"column":11,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":65,"endColumn":29},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":80,"column":33,"nodeType":"MemberExpression","messageId":"neverNullish","endLine":80,"endColumn":43},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":87,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":87,"endColumn":33},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":91,"column":10,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":91,"endColumn":34},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":91,"column":13,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":91,"endColumn":15,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3666,3668],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":91,"column":41,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":91,"endColumn":43,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[3694,3696],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":98,"column":11,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":98,"endColumn":33}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":14,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { Metadata } from 'next'\nimport { notFound } from 'next/navigation'\nimport { getAdapter } from '@/lib/db/core/dbal-client'\nimport { loadJSONPackage } from '@/lib/packages/json/functions/load-json-package'\nimport { renderJSONComponent } from '@/lib/packages/json/render-json-component'\nimport type { JSONComponent } from '@/lib/packages/json/types'\n\n/**\n * Root page handler with routing priority:\n * 1. God panel routes (PageConfig table) - user-configurable, highest priority\n * 2. Package default routes (InstalledPackage.config.defaultRoute) - package-defined fallback\n *\n * This allows god/supergod users to override any route through the admin panel,\n * while still having sensible defaults from packages.\n */\nexport default async function RootPage() {\n const adapter = getAdapter()\n\n // PRIORITY 1: Check god panel routes (PageConfig)\n const godPanelRoutes = await adapter.list('PageConfig', {\n filter: {\n path: '/',\n isPublished: true,\n },\n }) as { data: Array<{\n packageId: string\n component: string\n componentTree: string\n level: number\n requiresAuth: boolean\n }> }\n\n if (godPanelRoutes.data.length > 0) {\n const route = godPanelRoutes.data[0] as typeof godPanelRoutes.data[number] // Safe: length check ensures element exists\n\n // TODO: Implement proper session/user context for permission checks\n // For now, we'll allow access to public routes and skip auth checks\n // Full implementation requires:\n // 1. Session middleware to get current user from cookies\n // 2. User permission level check: user.level >= route.level\n // 3. Auth requirement: if (route.requiresAuth && !user) redirect('/login')\n \n // Permission level check (when user context is available)\n // const user = await getCurrentUser() // TODO: Implement getCurrentUser\n // if (user && user.level < route.level) {\n // return
Access Denied: Insufficient permissions
\n // }\n \n // Auth requirement check\n // if (route.requiresAuth && !user) {\n // redirect('/login')\n // }\n\n // If route has full component tree, render it directly\n if (route.componentTree !== null && route.componentTree !== undefined && route.componentTree.length > 0) {\n const componentDef = JSON.parse(route.componentTree) as unknown as JSONComponent\n return renderJSONComponent(componentDef, {}, {})\n }\n\n // Otherwise use the package + component reference\n if (route.packageId !== undefined && route.packageId !== null && route.component !== undefined && route.component !== null) {\n const pkg = await loadJSONPackage(`/home/rewrich/Documents/GitHub/metabuilder/packages/${route.packageId}`)\n const component = pkg?.components?.find(c => c.id === route.component || c.name === route.component)\n\n if (component !== null && component !== undefined) {\n return renderJSONComponent(component, {}, {})\n }\n }\n }\n\n // PRIORITY 2: Check package default routes (InstalledPackage.config.defaultRoute)\n const installedPackages = await adapter.list('InstalledPackage', {\n filter: {\n enabled: true,\n },\n }) as { data: Array<{ packageId: string; config: string }> }\n\n const homePackageRecord = installedPackages.data.find((pkg) => {\n try {\n const config = JSON.parse(pkg.config ?? '{}') as { defaultRoute?: string }\n return config.defaultRoute === '/'\n } catch {\n return false\n }\n })\n\n if (homePackageRecord !== null && homePackageRecord !== undefined) {\n const packageId = homePackageRecord.packageId\n const pkg = await loadJSONPackage(`/home/rewrich/Documents/GitHub/metabuilder/packages/${packageId}`)\n\n if ((pkg?.components !== null && pkg?.components !== undefined) && pkg.components.length > 0) {\n const pageComponent = pkg.components.find(c =>\n c.id === 'home_page' ||\n c.name === 'HomePage' ||\n c.name === 'Home'\n ) ?? pkg.components[0]\n\n if (pageComponent !== null && pageComponent !== undefined) {\n return renderJSONComponent(pageComponent, {}, {})\n }\n }\n }\n\n // No route found\n notFound()\n}\n\nexport const metadata: Metadata = {\n title: 'MetaBuilder - Home',\n description: 'Data-driven application platform',\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/providers.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/providers/providers-component.tsx","messages":[{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe array destructuring of a tuple element with an error typed value.","line":11,"column":10,"nodeType":"Identifier","messageId":"unsafeArrayPatternFromTuple","endLine":11,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe construction of a(n) `error` type typed value.","line":13,"column":7,"nodeType":"NewExpression","messageId":"unsafeNew","endLine":20,"endColumn":9},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":2,"message":"Unsafe return of a value of type error.","line":13,"column":7,"nodeType":"NewExpression","messageId":"unsafeReturn","endLine":20,"endColumn":9},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an error typed value.","line":54,"column":36,"nodeType":"Identifier","messageId":"anyAssignment","endLine":54,"endColumn":47}],"suppressedMessages":[],"errorCount":4,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use client'\n\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query'\nimport { useEffect, useMemo, useState } from 'react'\n\nimport { CssBaseline } from '@/fakemui'\n\nimport { ThemeContext, type ThemeMode } from './theme-context'\n\nexport function Providers({ children }: { children: React.ReactNode }) {\n const [queryClient] = useState(\n () =>\n new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 60 * 1000, // 1 minute\n retry: 1,\n },\n },\n })\n )\n\n const [mode, setMode] = useState('system')\n\n const resolvedMode = useMemo>(() => {\n if (mode === 'system') {\n return typeof window !== 'undefined' &&\n window.matchMedia('(prefers-color-scheme: dark)').matches\n ? 'dark'\n : 'light'\n }\n\n return mode\n }, [mode])\n\n useEffect(() => {\n const root = document.documentElement\n\n root.dataset.theme = resolvedMode\n root.style.colorScheme = resolvedMode\n }, [resolvedMode])\n\n const toggleTheme = () => {\n setMode(current => {\n if (current === 'light') return 'dark'\n if (current === 'dark') return 'system'\n return 'light'\n })\n }\n\n return (\n \n \n {children}\n \n )\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/providers/theme-context.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/providers/use-theme.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":7,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":7,"endColumn":23}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { useContext } from 'react'\n\nimport { ThemeContext } from './theme-context'\n\nexport function useTheme() {\n const context = useContext(ThemeContext)\n if (context === null || context === undefined) {\n throw new Error('useTheme must be used within Providers')\n }\n return context\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/app/ui/[[...slug]]/page.tsx","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":33,"column":31,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":33,"endColumn":56},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":59,"column":28,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":59,"endColumn":50}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { Metadata } from 'next'\nimport { notFound } from 'next/navigation'\n\nimport { UIPageRenderer } from '@/components/ui-page-renderer/UIPageRenderer'\nimport { loadPageFromDb } from '@/lib/ui-pages/load-page-from-db'\nimport { loadPageFromLuaPackages } from '@/lib/ui-pages/load-page-from-lua-packages'\n\ninterface PageProps {\n params: Promise<{\n slug?: string[]\n }>\n}\n\n/**\n * Generic dynamic route for database-driven UI pages\n * Handles all paths: /ui, /ui/login, /ui/dashboard, etc.\n *\n * Flow:\n * 1. JSON seed data → Database (via import-ui-pages.ts)\n * 2. Database → Load page record\n * 3. Lua actions → Execute if present\n * 4. UIPageRenderer → Generate React components\n * 5. User sees rendered page\n */\nexport default async function DynamicUIPage({ params }: PageProps) {\n const resolvedParams = await params\n const slug = resolvedParams.slug ?? []\n const path = '/' + slug.join('/')\n\n // Prefer Lua package-based UI pages, fallback to database-backed pages\n const rawPageData = (await loadPageFromLuaPackages(path)) ?? (await loadPageFromDb(path))\n\n if (rawPageData === null || rawPageData === undefined) {\n notFound()\n }\n\n // Transform PageConfig to UIPageData\n const pageData = {\n layout: rawPageData,\n actions: {},\n }\n\n // Check authentication if required\n // TODO: Add auth check based on pageData.requireAuth and pageData.requiredRole\n\n return \n}\n\n/**\n * Generate metadata for the page\n */\nexport async function generateMetadata({ params }: PageProps): Promise {\n const resolvedParams = await params\n const slug = resolvedParams.slug ?? []\n const path = '/' + slug.join('/')\n\n const pageData = (await loadPageFromLuaPackages(path)) ?? (await loadPageFromDb(path))\n\n if (pageData === null || pageData === undefined) {\n return {\n title: 'Page Not Found',\n }\n }\n\n return {\n title: pageData.title,\n description: `MetaBuilder - ${pageData.title}`,\n }\n}\n\n/**\n * Optional: Generate static params for known pages\n * This enables static generation at build time\n */\nexport function generateStaticParams() {\n // TODO: Query database for all active pages\n // For now, return empty array (all pages will be dynamic)\n return []\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/components/PackageStyleLoader.tsx","messages":[],"suppressedMessages":[{"ruleId":"no-console","severity":1,"message":"Unexpected console statement. Only these console methods are allowed: warn, error.","line":20,"column":7,"nodeType":"MemberExpression","messageId":"limited","endLine":20,"endColumn":18,"suggestions":[{"fix":{"range":[443,510],"text":""},"messageId":"removeConsole","data":{"propertyName":"log"},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":1,"message":"Unexpected console statement. Only these console methods are allowed: warn, error.","line":27,"column":13,"nodeType":"MemberExpression","messageId":"limited","endLine":27,"endColumn":24,"suggestions":[{"fix":{"range":[737,788],"text":""},"messageId":"removeConsole","data":{"propertyName":"log"},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"no-console","severity":1,"message":"Unexpected console statement. Only these console methods are allowed: warn, error.","line":39,"column":7,"nodeType":"MemberExpression","messageId":"limited","endLine":39,"endColumn":18,"suggestions":[{"fix":{"range":[1202,1311],"text":""},"messageId":"removeConsole","data":{"propertyName":"log"},"desc":"Remove the console.log()."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/components/get-component-icon.test.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/components/get-component-icon.tsx","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":54,"column":10,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":54,"endColumn":23}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { ComponentType, ReactElement } from 'react'\n\nimport {\n AccountCircle,\n Article,\n Autorenew,\n Chat,\n Checkbox,\n CropFree,\n CropPortrait,\n FormatAlignLeft,\n GridView,\n type IconProps,\n LocalOffer,\n LooksOne,\n Minus,\n TableChart,\n TextFields,\n ToggleOn,\n TouchApp,\n Tune,\n Verified,\n ViewColumn,\n ViewStream,\n WarningAmber,\n} from '@/fakemui/icons'\n\nconst iconMap: Record> = {\n Article,\n Card: CropPortrait,\n Chat,\n CheckSquare: Checkbox,\n CircleNotch: Autorenew,\n Columns: ViewColumn,\n CursorClick: TouchApp,\n FrameCorners: CropFree,\n GridFour: GridView,\n Minus,\n Seal: Verified,\n SlidersHorizontal: Tune,\n Stack: ViewStream,\n Table: TableChart,\n Tag: LocalOffer,\n TextAlignLeft: FormatAlignLeft,\n TextHOne: LooksOne,\n TextT: TextFields,\n ToggleRight: ToggleOn,\n UserCircle: AccountCircle,\n Warning: WarningAmber,\n}\n\nexport function getComponentIcon(iconName: string, props?: IconProps): ReactElement | null {\n const Icon = iconMap[iconName]\n return Icon !== null && Icon !== undefined ? : null\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/components/ui-page-renderer/UIPageRenderer.tsx","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/components/ui-page-renderer/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/__tests__/useAuth.roles.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":61,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":61,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":61,"column":31,"nodeType":"Identifier","messageId":"unsafeCall","endLine":61,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":62,"column":21,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":62,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":63,"column":9,"nodeType":"Identifier","messageId":"unsafeCall","endLine":63,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":64,"column":11,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":64,"endColumn":32},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":64,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":64,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":66,"column":21,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":66,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":67,"column":3,"nodeType":"Identifier","messageId":"unsafeCall","endLine":67,"endColumn":10},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":88,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":88,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":88,"column":33,"nodeType":"Identifier","messageId":"unsafeCall","endLine":88,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":95,"column":23,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":95,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":96,"column":11,"nodeType":"Identifier","messageId":"unsafeCall","endLine":96,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":97,"column":13,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":97,"endColumn":33},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":97,"column":20,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":97,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":100,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":100,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":102,"column":5,"nodeType":"Identifier","messageId":"unsafeCall","endLine":102,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":106,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":106,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":106,"column":33,"nodeType":"Identifier","messageId":"unsafeCall","endLine":106,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":110,"column":11,"nodeType":"Identifier","messageId":"unsafeCall","endLine":110,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":111,"column":13,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":111,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":111,"column":20,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":111,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":113,"column":23,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":113,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":115,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":115,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":117,"column":5,"nodeType":"Identifier","messageId":"unsafeCall","endLine":117,"endColumn":12}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":24,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { act, renderHook } from '@testing-library/react'\nimport { beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport { useAuth } from '@/hooks/useAuth'\nimport { fetchSession } from '@/lib/auth/api/fetch-session'\nimport { login as loginRequest } from '@/lib/auth/api/login'\nimport { logout as logoutRequest } from '@/lib/auth/api/logout'\nimport type { User } from '@/lib/level-types'\n\n// Simple waitFor implementation\nconst waitFor = async (callback: () => boolean | void, timeout = 1000) => {\n const start = Date.now()\n while (Date.now() - start < timeout) {\n try {\n const result = callback()\n if (result === false) continue\n return\n } catch {\n await new Promise(resolve => setTimeout(resolve, 50))\n }\n }\n throw new Error('waitFor timed out')\n}\n\nvi.mock('@/lib/auth/api/fetch-session', () => ({\n fetchSession: vi.fn(),\n}))\n\nvi.mock('@/lib/auth/api/login', () => ({\n login: vi.fn(),\n}))\n\nvi.mock('@/lib/auth/api/logout', () => ({\n logout: vi.fn(),\n}))\n\nconst mockFetchSession = vi.mocked(fetchSession)\nconst mockLogin = vi.mocked(loginRequest)\nconst mockLogout = vi.mocked(logoutRequest)\n\nconst createUser = (overrides?: Partial): User => ({\n id: 'user_1',\n username: 'alice',\n email: 'alice@example.com',\n role: 'user',\n createdAt: 1000,\n tenantId: undefined,\n profilePicture: undefined,\n bio: undefined,\n isInstanceOwner: false,\n ...overrides,\n})\n\nconst waitForIdle = async (result: { current: { isLoading: boolean } }) => {\n await waitFor(() => {\n expect(result.current.isLoading).toBe(false)\n })\n}\n\nconst resetAuthStore = async () => {\n const { result, unmount } = renderHook(() => useAuth())\n await waitForIdle(result)\n await act(async () => {\n await result.current.logout()\n })\n await waitForIdle(result)\n unmount()\n}\n\ndescribe('useAuth role mapping', () => {\n beforeEach(async () => {\n mockFetchSession.mockReset()\n mockLogin.mockReset()\n mockLogout.mockReset()\n mockFetchSession.mockResolvedValue(null)\n mockLogout.mockResolvedValue(undefined)\n\n await resetAuthStore()\n })\n\n it.each([\n { role: 'public', expectedLevel: 1 },\n { role: 'user', expectedLevel: 2 },\n { role: 'admin', expectedLevel: 4 },\n { role: 'supergod', expectedLevel: 6 },\n { role: 'unknown', expectedLevel: 0 },\n ])('applies level for role \"$role\"', async ({ role, expectedLevel }) => {\n const { result, unmount } = renderHook(() => useAuth())\n\n mockLogin.mockResolvedValue({\n success: true,\n user: createUser({ role }),\n })\n\n await waitForIdle(result)\n await act(async () => {\n await result.current.login('alice@example.com', 'password')\n })\n\n expect(result.current.user?.level).toBe(expectedLevel)\n\n unmount()\n })\n\n it('maps refreshed session roles to levels', async () => {\n const { result, unmount } = renderHook(() => useAuth())\n\n mockFetchSession.mockResolvedValue(createUser({ role: 'moderator' }))\n\n await act(async () => {\n await result.current.refresh()\n })\n await waitForIdle(result)\n\n expect(result.current.user?.level).toBe(3)\n\n unmount()\n })\n})\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/__tests__/useAuth.session.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":67,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":67,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":67,"column":31,"nodeType":"Identifier","messageId":"unsafeCall","endLine":67,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":68,"column":21,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":68,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":69,"column":9,"nodeType":"Identifier","messageId":"unsafeCall","endLine":69,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":70,"column":11,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":70,"endColumn":32},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":70,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":70,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":72,"column":21,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":72,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":73,"column":3,"nodeType":"Identifier","messageId":"unsafeCall","endLine":73,"endColumn":10},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":89,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":89,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":89,"column":33,"nodeType":"Identifier","messageId":"unsafeCall","endLine":89,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":91,"column":23,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":91,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":93,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":93,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":94,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":94,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":96,"column":5,"nodeType":"Identifier","messageId":"unsafeCall","endLine":96,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":100,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":100,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":100,"column":33,"nodeType":"Identifier","messageId":"unsafeCall","endLine":100,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":107,"column":23,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":107,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":108,"column":11,"nodeType":"Identifier","messageId":"unsafeCall","endLine":108,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":109,"column":13,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":109,"endColumn":33},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":109,"column":20,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":109,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":112,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":112,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":118,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":118,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":120,"column":5,"nodeType":"Identifier","messageId":"unsafeCall","endLine":120,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":124,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":124,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":124,"column":33,"nodeType":"Identifier","messageId":"unsafeCall","endLine":124,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":131,"column":23,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":131,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":132,"column":11,"nodeType":"Identifier","messageId":"unsafeCall","endLine":132,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":133,"column":13,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":133,"endColumn":33},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":133,"column":20,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":133,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":136,"column":11,"nodeType":"Identifier","messageId":"unsafeCall","endLine":136,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":137,"column":13,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":137,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":137,"column":20,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":137,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":140,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":140,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":141,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":141,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":143,"column":5,"nodeType":"Identifier","messageId":"unsafeCall","endLine":143,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":147,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":147,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":147,"column":33,"nodeType":"Identifier","messageId":"unsafeCall","endLine":147,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":158,"column":23,"nodeType":"Identifier","messageId":"unsafeArgument","endLine":158,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":159,"column":11,"nodeType":"Identifier","messageId":"unsafeCall","endLine":159,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":160,"column":13,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":160,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":160,"column":20,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":160,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":163,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":163,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .current on an `error` typed value.","line":169,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":169,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":171,"column":5,"nodeType":"Identifier","messageId":"unsafeCall","endLine":171,"endColumn":12},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":175,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":175,"endColumn":46},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":175,"column":19,"nodeType":"Identifier","messageId":"unsafeCall","endLine":175,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":176,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":176,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":176,"column":20,"nodeType":"Identifier","messageId":"unsafeCall","endLine":176,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":183,"column":23,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":183,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .result on an `error` typed value.","line":183,"column":29,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":183,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `{ current: { isLoading: boolean; }; }`.","line":184,"column":23,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":184,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .result on an `error` typed value.","line":184,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":184,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":186,"column":11,"nodeType":"Identifier","messageId":"unsafeCall","endLine":186,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":187,"column":13,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":187,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .result on an `error` typed value.","line":187,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":187,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .result on an `error` typed value.","line":190,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":190,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .result on an `error` typed value.","line":191,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":191,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":193,"column":11,"nodeType":"Identifier","messageId":"unsafeCall","endLine":193,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":194,"column":13,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":194,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .result on an `error` typed value.","line":194,"column":20,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":194,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .result on an `error` typed value.","line":197,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":197,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .result on an `error` typed value.","line":198,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":198,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":200,"column":5,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":200,"endColumn":18},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .unmount on an `error` typed value.","line":200,"column":11,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":200,"endColumn":18},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":201,"column":5,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":201,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .unmount on an `error` typed value.","line":201,"column":12,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":201,"endColumn":19}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":66,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { act, renderHook } from '@testing-library/react'\nimport { beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport { useAuth } from '@/hooks/useAuth'\nimport { fetchSession } from '@/lib/auth/api/fetch-session'\nimport { login as loginRequest } from '@/lib/auth/api/login'\nimport { logout as logoutRequest } from '@/lib/auth/api/logout'\nimport { register as registerRequest } from '@/lib/auth/api/register'\nimport type { User } from '@/lib/level-types'\n\n// Simple waitFor implementation\nconst waitFor = async (callback: () => boolean | void, timeout = 1000) => {\n const start = Date.now()\n while (Date.now() - start < timeout) {\n try {\n const result = callback()\n if (result === false) continue\n return\n } catch {\n await new Promise(resolve => setTimeout(resolve, 50))\n }\n }\n throw new Error('waitFor timed out')\n}\n\nvi.mock('@/lib/auth/api/fetch-session', () => ({\n fetchSession: vi.fn(),\n}))\n\nvi.mock('@/lib/auth/api/login', () => ({\n login: vi.fn(),\n}))\n\nvi.mock('@/lib/auth/api/register', () => ({\n register: vi.fn(),\n}))\n\nvi.mock('@/lib/auth/api/logout', () => ({\n logout: vi.fn(),\n}))\n\nconst mockFetchSession = vi.mocked(fetchSession)\nconst mockLogin = vi.mocked(loginRequest)\nconst mockRegister = vi.mocked(registerRequest)\nconst mockLogout = vi.mocked(logoutRequest)\n\nconst createUser = (overrides?: Partial): User => ({\n id: 'user_1',\n username: 'alice',\n email: 'alice@example.com',\n role: 'user',\n createdAt: 1000,\n tenantId: undefined,\n profilePicture: undefined,\n bio: undefined,\n isInstanceOwner: false,\n ...overrides,\n})\n\nconst waitForIdle = async (result: { current: { isLoading: boolean } }) => {\n await waitFor(() => {\n expect(result.current.isLoading).toBe(false)\n })\n}\n\nconst resetAuthStore = async () => {\n const { result, unmount } = renderHook(() => useAuth())\n await waitForIdle(result)\n await act(async () => {\n await result.current.logout()\n })\n await waitForIdle(result)\n unmount()\n}\n\ndescribe('useAuth session flows', () => {\n beforeEach(async () => {\n mockFetchSession.mockReset()\n mockLogin.mockReset()\n mockRegister.mockReset()\n mockLogout.mockReset()\n mockFetchSession.mockResolvedValue(null)\n mockLogout.mockResolvedValue(undefined)\n\n await resetAuthStore()\n })\n\n it('starts unauthenticated after session check', async () => {\n const { result, unmount } = renderHook(() => useAuth())\n\n await waitForIdle(result)\n\n expect(result.current.user).toBeNull()\n expect(result.current.isAuthenticated).toBe(false)\n\n unmount()\n })\n\n it('authenticates on login', async () => {\n const { result, unmount } = renderHook(() => useAuth())\n\n mockLogin.mockResolvedValue({\n success: true,\n user: createUser(),\n })\n\n await waitForIdle(result)\n await act(async () => {\n await result.current.login('alice@example.com', 'password')\n })\n\n expect(result.current.user).toMatchObject({\n id: 'user_1',\n email: 'alice@example.com',\n username: 'alice',\n level: 2,\n })\n expect(result.current.isAuthenticated).toBe(true)\n\n unmount()\n })\n\n it('clears user on logout', async () => {\n const { result, unmount } = renderHook(() => useAuth())\n\n mockLogin.mockResolvedValue({\n success: true,\n user: createUser(),\n })\n\n await waitForIdle(result)\n await act(async () => {\n await result.current.login('alice@example.com', 'password')\n })\n\n await act(async () => {\n await result.current.logout()\n })\n\n expect(result.current.user).toBeNull()\n expect(result.current.isAuthenticated).toBe(false)\n\n unmount()\n })\n\n it('registers and authenticates', async () => {\n const { result, unmount } = renderHook(() => useAuth())\n\n mockRegister.mockResolvedValue({\n success: true,\n user: createUser({\n id: 'user_2',\n username: 'newbie',\n email: 'newbie@example.com',\n }),\n })\n\n await waitForIdle(result)\n await act(async () => {\n await result.current.register('newbie', 'newbie@example.com', 'password')\n })\n\n expect(result.current.user).toMatchObject({\n id: 'user_2',\n email: 'newbie@example.com',\n username: 'newbie',\n level: 2,\n })\n expect(result.current.isAuthenticated).toBe(true)\n\n unmount()\n })\n\n it('syncs state across hooks', async () => {\n const first = renderHook(() => useAuth())\n const second = renderHook(() => useAuth())\n\n mockLogin.mockResolvedValue({\n success: true,\n user: createUser({ email: 'sync@example.com', username: 'sync' }),\n })\n\n await waitForIdle(first.result)\n await waitForIdle(second.result)\n\n await act(async () => {\n await first.result.current.login('sync@example.com', 'password')\n })\n\n expect(second.result.current.isAuthenticated).toBe(true)\n expect(second.result.current.user?.email).toBe('sync@example.com')\n\n await act(async () => {\n await second.result.current.logout()\n })\n\n expect(first.result.current.isAuthenticated).toBe(false)\n expect(first.result.current.user).toBeNull()\n\n first.unmount()\n second.unmount()\n })\n})\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/auth/auth-store.ts","messages":[{"ruleId":"@typescript-eslint/prefer-readonly","severity":1,"message":"Member 'listeners' is never reassigned; mark it as `readonly`.","line":21,"column":3,"nodeType":null,"messageId":"preferReadonly","endLine":21,"endColumn":20,"fix":{"range":[579,579],"text":"readonly "}},{"ruleId":"@typescript-eslint/no-confusing-void-expression","severity":1,"message":"Returning a void expression from an arrow function shorthand is forbidden. Please add braces to the arrow function.","line":37,"column":40,"nodeType":"CallExpression","messageId":"invalidVoidExprArrow","endLine":37,"endColumn":50,"fix":{"range":[988,998],"text":"{ listener(); }"}},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":129,"column":28,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":129,"endColumn":46}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":2,"source":"/**\n * @file auth-store.ts\n * @description Authentication state management store\n */\n\nimport { fetchSession } from '@/lib/auth/api/fetch-session'\nimport { login as loginRequest } from '@/lib/auth/api/login'\nimport { logout as logoutRequest } from '@/lib/auth/api/logout'\nimport { register as registerRequest } from '@/lib/auth/api/register'\n\nimport type { AuthState } from './auth-types'\nimport { mapUserToAuthUser } from './utils/map-user'\n\nexport class AuthStore {\n private state: AuthState = {\n user: null,\n isAuthenticated: false,\n isLoading: false,\n }\n\n private listeners = new Set<() => void>()\n private sessionCheckPromise: Promise | null = null\n\n getState(): AuthState {\n return this.state\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n private setState(newState: AuthState): void {\n this.state = newState\n this.listeners.forEach(listener => listener())\n }\n\n async ensureSessionChecked(): Promise {\n this.sessionCheckPromise ??= this.refresh().finally(() => {\n this.sessionCheckPromise = null\n })\n return this.sessionCheckPromise\n }\n\n async login(identifier: string, password: string): Promise {\n this.setState({\n ...this.state,\n isLoading: true,\n })\n\n try {\n const result = await loginRequest(identifier, password)\n \n if (!result.success || result.user === null) {\n this.setState({\n ...this.state,\n isLoading: false,\n })\n throw new Error(result.error ?? 'Login failed')\n }\n \n this.setState({\n user: mapUserToAuthUser(result.user),\n isAuthenticated: true,\n isLoading: false,\n })\n } catch (error) {\n this.setState({\n ...this.state,\n isLoading: false,\n })\n throw error\n }\n }\n\n async register(username: string, email: string, password: string): Promise {\n this.setState({\n ...this.state,\n isLoading: true,\n })\n\n try {\n const result = await registerRequest(username, email, password)\n \n if (!result.success || result.user === null) {\n this.setState({\n ...this.state,\n isLoading: false,\n })\n throw new Error(result.error ?? 'Registration failed')\n }\n \n this.setState({\n user: mapUserToAuthUser(result.user),\n isAuthenticated: true,\n isLoading: false,\n })\n } catch (error) {\n this.setState({\n ...this.state,\n isLoading: false,\n })\n throw error\n }\n }\n\n async logout(): Promise {\n try {\n await logoutRequest()\n } finally {\n this.setState({\n user: null,\n isAuthenticated: false,\n isLoading: false,\n })\n }\n }\n\n async refresh(): Promise {\n this.setState({\n ...this.state,\n isLoading: true,\n })\n\n try {\n const user = await fetchSession()\n if (user !== null && user !== undefined) {\n this.setState({\n user: mapUserToAuthUser(user),\n isAuthenticated: true,\n isLoading: false,\n })\n } else {\n this.setState({\n user: null,\n isAuthenticated: false,\n isLoading: false,\n })\n }\n } catch (error) {\n this.setState({\n user: null,\n isAuthenticated: false,\n isLoading: false,\n })\n console.error('Failed to refresh session', error)\n }\n }\n}\n\nexport const authStore = new AuthStore()\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/auth/auth-types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/auth/utils/map-user.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/auth/utils/role-levels.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/data/useLevelRouting.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/data/useResolvedUser.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/use-dbal/use-blob-storage.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/use-dbal/use-cached-data.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/use-dbal/use-dbal.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/use-dbal/use-kv-store.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/use-mobile.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/useAuth.ts","messages":[{"ruleId":"@typescript-eslint/no-confusing-void-expression","severity":1,"message":"Returning a void expression from an arrow function shorthand is forbidden. Please add braces to the arrow function.","line":14,"column":51,"nodeType":"CallExpression","messageId":"invalidVoidExprArrow","endLine":14,"endColumn":88,"fix":{"range":[463,500],"text":"{ setState({ ...authStore.getState() }); }"}}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"/**\n * useAuth hook - authentication state management\n * Provides user authentication state and methods\n */\nimport { useCallback, useEffect, useState } from 'react'\n\nimport { authStore } from './auth/auth-store'\nimport type { AuthState, UseAuthReturn } from './auth/auth-types'\n\nexport function useAuth(): UseAuthReturn {\n const [state, setState] = useState(authStore.getState())\n\n useEffect(() => {\n const unsubscribe = authStore.subscribe(() => setState({ ...authStore.getState() }))\n void authStore.ensureSessionChecked()\n return unsubscribe\n }, [])\n\n const login = useCallback(async (identifier: string, password: string) => {\n await authStore.login(identifier, password)\n }, [])\n\n const register = useCallback(async (username: string, email: string, password: string) => {\n await authStore.register(username, email, password)\n }, [])\n\n const logout = useCallback(async () => {\n await authStore.logout()\n }, [])\n\n const refresh = useCallback(async () => {\n await authStore.refresh()\n }, [])\n\n return {\n ...state,\n login,\n register,\n logout,\n refresh,\n }\n}\n\nexport default useAuth\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/useAutoRefresh.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/useCodeEditor.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/useDBAL.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":35,"column":15,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":35,"endColumn":19,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[717,721],"text":"(Boolean(body))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":38,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":38,"endColumn":60},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":40,"column":27,"nodeType":"MemberExpression","messageId":"conditionErrorNullableObject","endLine":40,"endColumn":39,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[855,867],"text":"(result.error != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":41,"column":21,"nodeType":"MemberExpression","messageId":"conditionErrorNullableObject","endLine":41,"endColumn":33,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[891,903],"text":"(result.error != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":41,"column":34,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":41,"endColumn":36,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[904,906],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":63,"column":27,"nodeType":"Identifier","messageId":"conditionErrorNullableObject","endLine":63,"endColumn":33,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[1487,1493],"text":"(params != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * useDBAL hook - Basic DBAL API client using fetch\n */\n\nimport { useState, useCallback } from 'react'\n\ninterface DBALError {\n message: string\n code?: string\n}\n\ninterface DBALResponse {\n data?: T\n error?: DBALError\n}\n\nexport function useDBAL() {\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState(null)\n\n const request = useCallback(async (\n method: string,\n endpoint: string,\n body?: unknown\n ): Promise => {\n setLoading(true)\n setError(null)\n\n try {\n const response = await fetch(`/api/dbal/${endpoint}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n })\n\n const result: DBALResponse = await response.json()\n\n if (!response.ok || result.error) {\n const err = result.error || { message: 'Request failed' }\n setError(err)\n throw new Error(err.message)\n }\n\n return result.data ?? null\n } catch (err) {\n const error = err instanceof Error ? { message: err.message } : { message: 'Unknown error' }\n setError(error)\n throw err\n } finally {\n setLoading(false)\n }\n }, [])\n\n return {\n loading,\n error,\n get: async (entity: string, id: string) => {\n return request('GET', `${entity}/${id}`)\n },\n list: async (entity: string, params?: Record) => {\n const queryString = params ? `?${new URLSearchParams(params as Record).toString()}` : ''\n return request('GET', `${entity}${queryString}`)\n },\n create: async (entity: string, data: unknown) => {\n return request('POST', entity, data)\n },\n update: async (entity: string, id: string, data: unknown) => {\n return request('PUT', `${entity}/${id}`, data)\n },\n delete: async (entity: string, id: string) => {\n return request('DELETE', `${entity}/${id}`)\n },\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/useFileTree.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/useGitHubFetcher.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/useKV.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":35,"column":15,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":35,"endColumn":19,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[751,755],"text":"(Boolean(body))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":38,"column":13,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":38,"endColumn":58},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":40,"column":27,"nodeType":"MemberExpression","messageId":"conditionErrorNullableObject","endLine":40,"endColumn":39,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[887,899],"text":"(result.error != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":41,"column":21,"nodeType":"MemberExpression","messageId":"conditionErrorNullableObject","endLine":41,"endColumn":33,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[923,935],"text":"(result.error != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":41,"column":34,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":41,"endColumn":36,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[936,938],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":69,"column":27,"nodeType":"Identifier","messageId":"conditionErrorNullableString","endLine":69,"endColumn":33,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[1647,1653],"text":"(prefix != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[1647,1653],"text":"(prefix ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[1647,1653],"text":"(Boolean(prefix))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * useKV hook - Basic key-value store using DBAL KV API\n */\n\nimport { useState, useCallback } from 'react'\n\ninterface KVError {\n message: string\n code?: string\n}\n\ninterface KVResponse {\n data?: T\n error?: KVError\n}\n\nexport function useKV(namespace: string = 'default') {\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState(null)\n\n const request = useCallback(async (\n method: string,\n endpoint: string,\n body?: unknown\n ): Promise => {\n setLoading(true)\n setError(null)\n\n try {\n const response = await fetch(`/api/kv/${namespace}/${endpoint}`, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n },\n body: body ? JSON.stringify(body) : undefined,\n })\n\n const result: KVResponse = await response.json()\n\n if (!response.ok || result.error) {\n const err = result.error || { message: 'Request failed' }\n setError(err)\n throw new Error(err.message)\n }\n\n return result.data ?? null\n } catch (err) {\n const error = err instanceof Error ? { message: err.message } : { message: 'Unknown error' }\n setError(error)\n throw err\n } finally {\n setLoading(false)\n }\n }, [namespace])\n\n return {\n loading,\n error,\n get: async (key: string) => {\n return request('GET', key)\n },\n set: async (key: string, value: unknown) => {\n return request('PUT', key, { value })\n },\n delete: async (key: string) => {\n return request('DELETE', key)\n },\n list: async (prefix?: string) => {\n const queryString = prefix ? `?prefix=${encodeURIComponent(prefix)}` : ''\n return request('GET', `_list${queryString}`)\n },\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/useLevelRouting.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/hooks/useResolvedUser.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/api/read-json.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/auth/api/fetch-session.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":24,"column":39,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":24,"endColumn":60},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":31,"column":29,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":31,"endColumn":50}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Fetch current session\n * \n * Retrieves the current user based on session token from cookies or headers\n */\n\nimport type { User } from '@/lib/types/level-types'\nimport { getSessionByToken } from '@/lib/db/sessions/getters/get-session-by-token'\nimport { mapUserRecord } from '@/lib/db/users/map-user-record'\nimport { getAdapter } from '@/lib/db/core/dbal-client'\nimport { cookies } from 'next/headers'\n\n/**\n * Fetch the current session user\n * \n * @returns User if session is valid, null otherwise\n */\nexport async function fetchSession(): Promise {\n try {\n // Get session token from cookies\n const cookieStore = await cookies()\n const sessionToken = cookieStore.get('session_token')?.value\n\n if (sessionToken === undefined || sessionToken === null || sessionToken.length === 0) {\n return null\n }\n\n // Get session from token\n const session = await getSessionByToken(sessionToken)\n \n if (session === null || session === undefined) {\n return null\n }\n\n // Get user from session\n const adapter = getAdapter()\n const userRecord = await adapter.findFirst('User', {\n where: { id: session.userId },\n })\n\n if (userRecord === null || userRecord === undefined) {\n return null\n }\n\n const user = mapUserRecord(userRecord as Record)\n return user\n } catch (error) {\n console.error('Error fetching session:', error)\n return null\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/auth/api/login.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/auth/api/logout.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/auth/api/register.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/compiler/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/component-catalog.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/component-registry.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/components/component-catalog.ts","messages":[{"ruleId":"@typescript-eslint/prefer-readonly","severity":1,"message":"Member 'components' is never reassigned; mark it as `readonly`.","line":16,"column":3,"nodeType":null,"messageId":"preferReadonly","endLine":16,"endColumn":21,"fix":{"range":[323,323],"text":"readonly "}}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"/**\n * Component catalog for registering and retrieving components\n */\n\nexport interface ComponentCatalogEntry {\n name: string\n component: React.ComponentType\n description?: string\n}\n\n/**\n * Component catalog registry\n * TODO: Implement full component catalog functionality\n */\nexport class ComponentCatalog {\n private components = new Map()\n\n register(name: string, entry: ComponentCatalogEntry): void {\n this.components.set(name, entry)\n }\n\n get(name: string): ComponentCatalogEntry | undefined {\n return this.components.get(name)\n }\n\n getAll(): ComponentCatalogEntry[] {\n return Array.from(this.components.values())\n }\n}\n\n// Singleton instance\nexport const componentCatalog = new ComponentCatalog()\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/components/component-registry.ts","messages":[{"ruleId":"@typescript-eslint/prefer-readonly","severity":1,"message":"Member 'registry' is never reassigned; mark it as `readonly`.","line":17,"column":3,"nodeType":null,"messageId":"preferReadonly","endLine":17,"endColumn":19,"fix":{"range":[310,310],"text":"readonly "}}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":1,"source":"/**\n * Component registry for managing component metadata\n */\n\nexport interface ComponentMetadata {\n id: string\n name: string\n type: string\n props?: Record\n}\n\n/**\n * Component registry\n * TODO: Implement full component registry functionality\n */\nexport class ComponentRegistry {\n private registry = new Map()\n\n register(id: string, metadata: ComponentMetadata): void {\n this.registry.set(id, metadata)\n }\n\n get(id: string): ComponentMetadata | undefined {\n return this.registry.get(id)\n }\n\n getAll(): ComponentMetadata[] {\n return Array.from(this.registry.values())\n }\n}\n\n// Singleton instance\nexport const componentRegistry = new ComponentRegistry()\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/config/prisma.ts","messages":[{"ruleId":"@typescript-eslint/no-redundant-type-constituents","severity":1,"message":"'PrismaClient' is an 'error' type that acts as 'any' and overrides all other types in this union type.","line":9,"column":11,"nodeType":"TSTypeReference","messageId":"errorTypeOverrides","endLine":9,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an error typed value.","line":12,"column":14,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":16,"endColumn":5},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe construction of a(n) `error` type typed value.","line":14,"column":3,"nodeType":"NewExpression","messageId":"unsafeNew","endLine":16,"endColumn":5},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":2,"message":"Unsafe assignment of an error typed value.","line":19,"column":3,"nodeType":"AssignmentExpression","messageId":"anyAssignment","endLine":19,"endColumn":34}],"suppressedMessages":[],"errorCount":3,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Prisma Client singleton instance\n * Prevents multiple instances in development with hot reloading\n */\n\nimport { PrismaClient } from '@prisma/client'\n\nconst globalForPrisma = globalThis as unknown as {\n prisma: PrismaClient | undefined\n}\n\nexport const prisma =\n globalForPrisma.prisma ??\n new PrismaClient({\n log: process.env.NODE_ENV === 'development' ? ['error', 'warn'] : ['error'],\n })\n\nif (process.env.NODE_ENV !== 'production') {\n globalForPrisma.prisma = prisma\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/database-dbal/core/get-dbal.server.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/database-dbal/core/initialize-dbal.server.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/database-dbal/users/dbal-add-user.server.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/database-dbal/users/dbal-delete-user.server.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/database-dbal/users/dbal-get-user-by-id.server.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/database-dbal/users/dbal-get-users.server.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/database-dbal/users/dbal-update-user.server.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/database.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/app-config/get-app-config.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":39,"column":30,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":39,"endColumn":52}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { beforeEach, describe, expect, it, vi } from 'vitest'\n\nconst mockList = vi.fn()\nconst mockAdapter = { list: mockList }\n\nvi.mock('../core/dbal-client', () => ({\n getAdapter: () => mockAdapter,\n}))\n\nimport { getAppConfig } from './get-app-config'\n\ndescribe('getAppConfig', () => {\n beforeEach(() => {\n mockList.mockReset()\n })\n\n it.each([\n { name: 'null when empty', dbData: [], expected: null },\n {\n name: 'parsed config',\n dbData: [\n {\n id: 'app1',\n name: 'Test App',\n schemas: '[]',\n workflows: '[]',\n luaScripts: '[]',\n pages: '[]',\n theme: '{}',\n },\n ],\n expected: { id: 'app1', name: 'Test App' },\n },\n ])('should return $name', async ({ dbData, expected }) => {\n mockList.mockResolvedValue({ data: dbData })\n\n const result = await getAppConfig()\n\n if (expected !== null && expected !== undefined) {\n expect(result).toMatchObject(expected)\n } else {\n expect(result).toBeNull()\n }\n })\n})\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/app-config/get-app-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/app-config/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/app-config/set-app-config.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/app-config/set-app-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/auth/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/auth/queries/authenticate-user.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/auth/queries/get-user-by-email.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/auth/queries/get-user-by-email.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":18,"column":11,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":18,"endColumn":37}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport type { User } from '@/lib/types/level-types'\nimport { mapUserRecord } from '../../users/map-user-record'\n\n/**\n * Get user by email from DBAL.\n * Single-responsibility lambda for email lookup.\n */\nexport const getUserByEmail = async (\n email: string,\n options?: { tenantId?: string }\n): Promise => {\n const adapter = getAdapter()\n\n const record = await adapter.findFirst('User', {\n where: {\n email,\n ...(options?.tenantId !== null && options?.tenantId !== undefined ? { tenantId: options.tenantId } : {}),\n },\n })\n\n if (record === null || record === undefined) {\n return null\n }\n\n return mapUserRecord(record as Record)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/auth/queries/get-user-by-username.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/auth/queries/get-user-by-username.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":18,"column":11,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":18,"endColumn":37}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport type { User } from '@/lib/types/level-types'\nimport { mapUserRecord } from '../../users/map-user-record'\n\n/**\n * Get user by username from DBAL.\n * Single-responsibility lambda for username lookup.\n */\nexport const getUserByUsername = async (\n username: string,\n options?: { tenantId?: string }\n): Promise => {\n const adapter = getAdapter()\n\n const record = await adapter.findFirst('User', {\n where: {\n username,\n ...(options?.tenantId !== null && options?.tenantId !== undefined ? { tenantId: options.tenantId } : {}),\n },\n })\n\n if (record === null || record === undefined) {\n return null\n }\n\n return mapUserRecord(record as Record)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/comments/crud/add-comment.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/comments/crud/add-comment.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/comments/crud/delete-comment.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/comments/crud/delete-comment.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/comments/crud/get-comments.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/comments/crud/get-comments.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/comments/crud/set-comments.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/comments/crud/set-comments.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/comments/crud/update-comment.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/comments/crud/update-comment.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/comments/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/config/crud/operations/add-component-config.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":12,"column":27,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":12,"endColumn":63}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../../../core/dbal-client'\nimport type { ComponentConfig } from '../../../types'\n\nexport async function addComponentConfig(config: ComponentConfig): Promise {\n const adapter = getAdapter()\n await adapter.create('ComponentConfig', {\n id: config.id,\n componentId: config.componentId,\n props: JSON.stringify(config.props),\n styles: JSON.stringify(config.styles),\n events: JSON.stringify(config.events),\n conditionalRendering: config.conditionalRendering !== null && config.conditionalRendering !== undefined\n ? JSON.stringify(config.conditionalRendering)\n : null,\n })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/config/crud/operations/delete-component-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/config/crud/operations/update-component-config.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":15,"column":33,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":15,"endColumn":70},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":15,"column":74,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":15,"endColumn":116}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../../../core/dbal-client'\nimport type { ComponentConfig } from '../../../types'\n\nexport async function updateComponentConfig(\n configId: string,\n updates: Partial\n): Promise {\n const adapter = getAdapter()\n const data: Record = {}\n if (updates.componentId !== undefined) data.componentId = updates.componentId\n if (updates.props !== undefined) data.props = JSON.stringify(updates.props)\n if (updates.styles !== undefined) data.styles = JSON.stringify(updates.styles)\n if (updates.events !== undefined) data.events = JSON.stringify(updates.events)\n if (updates.conditionalRendering !== undefined) {\n data.conditionalRendering = updates.conditionalRendering !== null && updates.conditionalRendering !== undefined\n ? JSON.stringify(updates.conditionalRendering)\n : null\n }\n await adapter.update('ComponentConfig', configId, data)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/config/get-component-configs.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/config/get-component-configs.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/config/set-component-configs.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/config/set-component-configs.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":25,"column":29,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":25,"endColumn":65}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport type { ComponentConfig } from '../types'\n\ntype DBALComponentConfigRecord = {\n id: string\n}\n\nexport async function setComponentConfigs(configs: Record): Promise {\n const adapter = getAdapter()\n\n // Delete existing configs\n const existing = (await adapter.list('ComponentConfig')) as { data: DBALComponentConfigRecord[] }\n for (const c of existing.data) {\n await adapter.delete('ComponentConfig', c.id)\n }\n\n // Create new configs\n for (const config of Object.values(configs)) {\n await adapter.create('ComponentConfig', {\n id: config.id,\n componentId: config.componentId,\n props: JSON.stringify(config.props),\n styles: JSON.stringify(config.styles),\n events: JSON.stringify(config.events),\n conditionalRendering: config.conditionalRendering !== null && config.conditionalRendering !== undefined\n ? JSON.stringify(config.conditionalRendering)\n : null,\n })\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/hierarchy/get-component-hierarchy.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/hierarchy/get-component-hierarchy.ts","messages":[{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a ternary expression, as it is simpler to read.","line":21,"column":17,"nodeType":"ConditionalExpression","messageId":"preferNullishOverTernary","endLine":21,"endColumn":98,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[630,711],"text":"node.parentId ?? undefined"},"desc":"Fix to nullish coalescing operator (`??`)."}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport type { ComponentNode } from '../types'\n\ntype DBALComponentNodeRecord = {\n id: string\n type: string\n parentId?: string | null\n childIds: string\n order: number\n pageId: string\n}\n\nexport async function getComponentHierarchy(): Promise> {\n const adapter = getAdapter()\n const result = (await adapter.list('ComponentNode')) as { data: DBALComponentNodeRecord[] }\n const hierarchy: Record = {}\n for (const node of result.data) {\n hierarchy[node.id] = {\n id: node.id,\n type: node.type,\n parentId: node.parentId !== null && node.parentId !== undefined ? node.parentId : undefined,\n childIds: JSON.parse(node.childIds) as string[],\n order: node.order,\n pageId: node.pageId,\n }\n }\n return hierarchy\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/hierarchy/set-component-hierarchy.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/hierarchy/set-component-hierarchy.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/node/crud/add-component-node.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/node/crud/add-component-node.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/node/crud/delete-component-node.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/node/crud/delete-component-node.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/node/crud/update-component-node.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/node/crud/update-component-node.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/components/types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/core/dbal-client.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/core/dbal-client/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/core/entities.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/core/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/core/initialize-database.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe call of a(n) `error` type typed value.","line":8,"column":11,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":8,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":2,"message":"Unsafe member access .$connect on an `error` typed value.","line":8,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":8,"endColumn":26}],"suppressedMessages":[],"errorCount":2,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { prisma } from '../../config/prisma'\n\n/**\n * Initialize database connection\n */\nexport async function initializeDatabase(): Promise {\n try {\n await prisma.$connect()\n // Database initialized successfully\n } catch (error) {\n console.error('Failed to initialize database:', error)\n throw error\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/core/operations.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/core/prisma.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/core/types.ts","messages":[{"ruleId":"@typescript-eslint/consistent-type-imports","severity":1,"message":"`import()` type annotations are forbidden.","line":70,"column":12,"nodeType":"TSImportType","messageId":"noImportTypeAnnotations","endLine":70,"endColumn":52},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":1,"message":"`import()` type annotations are forbidden.","line":71,"column":26,"nodeType":"TSImportType","messageId":"noImportTypeAnnotations","endLine":71,"endColumn":80},{"ruleId":"@typescript-eslint/consistent-type-imports","severity":1,"message":"`import()` type annotations are forbidden.","line":72,"column":15,"nodeType":"TSImportType","messageId":"noImportTypeAnnotations","endLine":72,"endColumn":47}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * CSS category configuration\n */\nexport interface CssCategory {\n name: string\n classes: string[]\n}\n\n/**\n * Dropdown configuration\n */\nexport interface DropdownConfig {\n id: string\n name: string\n label: string\n options: Array<{ value: string; label: string }>\n}\n\n/**\n * Component node in hierarchy\n */\nexport interface ComponentNode {\n id: string\n name?: string\n type: string\n parentId?: string\n childIds?: string[]\n order?: number\n pageId?: string\n}\n\n/**\n * Component configuration\n */\nexport interface ComponentConfig {\n id: string\n componentId: string\n props: Record\n styles: Record\n events?: Record\n conditionalRendering?: {\n condition: string\n luaScriptId?: string\n }\n}\n\nimport type { User, Workflow, LuaScript, PageConfig, AppConfiguration, Comment } from '../../types/level-types'\nimport type { ModelSchema } from '../../types/schema-types'\n\n/**\n * Full database schema type\n */\nexport interface DatabaseSchema {\n users: User[]\n credentials: Record\n workflows: Workflow[]\n luaScripts: LuaScript[]\n pages: PageConfig[]\n schemas: ModelSchema[]\n appConfig: AppConfiguration\n comments: Comment[]\n componentHierarchy: Record\n componentConfigs: Record\n godCredentialsExpiry: number\n passwordChangeTimestamps: Record\n firstLoginFlags: Record\n godCredentialsExpiryDuration: number\n cssClasses: CssCategory[]\n dropdownConfigs: DropdownConfig[]\n tenants: import('../../types/level-types').Tenant[]\n powerTransferRequests: import('../../types/level-types').PowerTransferRequest[]\n smtpConfig: import('../password').SMTPConfig\n passwordResetTokens: Record\n}\n\n/**\n * Database keys enum\n */\nexport const DB_KEYS = {\n USERS: 'db_users',\n CREDENTIALS: 'db_credentials',\n WORKFLOWS: 'db_workflows',\n LUA_SCRIPTS: 'db_lua_scripts',\n PAGES: 'db_pages',\n SCHEMAS: 'db_schemas',\n APP_CONFIG: 'db_app_config',\n COMMENTS: 'db_comments',\n COMPONENT_HIERARCHY: 'db_component_hierarchy',\n COMPONENT_CONFIGS: 'db_component_configs',\n GOD_CREDENTIALS_EXPIRY: 'db_god_credentials_expiry',\n PASSWORD_CHANGE_TIMESTAMPS: 'db_password_change_timestamps',\n FIRST_LOGIN_FLAGS: 'db_first_login_flags',\n GOD_CREDENTIALS_EXPIRY_DURATION: 'db_god_credentials_expiry_duration',\n CSS_CLASSES: 'db_css_classes',\n DROPDOWN_CONFIGS: 'db_dropdown_configs',\n INSTALLED_PACKAGES: 'db_installed_packages',\n PACKAGE_DATA: 'db_package_data',\n TENANTS: 'db_tenants',\n POWER_TRANSFER_REQUESTS: 'db_power_transfer_requests',\n SMTP_CONFIG: 'db_smtp_config',\n PASSWORD_RESET_TOKENS: 'db_password_reset_tokens',\n} as const\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/css-classes/crud/add-css-category.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/css-classes/crud/delete-css-category.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":9,"column":28,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":9,"endColumn":50}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\n\n/**\n * Delete a CSS class category\n */\nexport async function deleteCssCategory(categoryName: string): Promise {\n const adapter = getAdapter()\n const existing = await adapter.findFirst('CssCategory', { where: { name: categoryName } }) as { id: string | number } | null\n if (existing === null || existing === undefined) {\n return\n }\n await adapter.delete('CssCategory', existing.id)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/css-classes/crud/get-css-classes.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/css-classes/crud/set-css-classes.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":12,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":12,"endColumn":26},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":12,"column":13,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":12,"endColumn":15,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[428,430],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":12,"column":34,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":12,"endColumn":36,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[449,451],"text":"."},"desc":"Remove unnecessary optional chain"}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport type { CssCategory } from '../types'\n\n/**\n * Set all CSS class categories (replaces existing)\n */\nexport async function setCssClasses(classes: CssCategory[]): Promise {\n const adapter = getAdapter()\n // Delete all existing\n const existing = await adapter.list('CssCategory')\n for (const item of existing.data as Array<{ id?: string | number }>) {\n if (item?.id !== null && item?.id !== undefined) {\n await adapter.delete('CssCategory', item.id)\n }\n }\n // Create new ones\n for (const category of classes) {\n await adapter.create('CssCategory', {\n name: category.name,\n classes: JSON.stringify(category.classes),\n })\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/css-classes/crud/update-css-category.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":10,"column":28,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":10,"endColumn":50}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport type { CssCategory } from '../types'\n\n/**\n * Update classes in an existing CSS category\n */\nexport async function updateCssCategory(categoryName: string, updates: CssCategory): Promise {\n const adapter = getAdapter()\n const existing = await adapter.findFirst('CssCategory', { where: { name: categoryName } }) as { id: string | number } | null\n if (existing === null || existing === undefined) {\n throw new Error(`CssCategory not found: ${categoryName}`)\n }\n\n await adapter.update('CssCategory', existing.id, {\n name: updates.name,\n classes: JSON.stringify(updates.classes),\n })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/css-classes/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/css-classes/types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/clear-database.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":43,"column":13,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":43,"endColumn":24}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../core/dbal-client'\n\nconst ENTITY_TYPES = [\n 'User',\n 'Credential',\n 'Workflow',\n 'LuaScript',\n 'PageConfig',\n 'ModelSchema',\n 'AppConfiguration',\n 'Comment',\n 'ComponentNode',\n 'ComponentConfig',\n 'SystemConfig',\n 'CssCategory',\n 'DropdownConfig',\n 'InstalledPackage',\n 'PackageData',\n 'Tenant',\n 'PowerTransferRequest',\n 'SMTPConfig',\n 'PasswordResetToken',\n] as const\n\ntype DBALDeleteCandidate = {\n id?: string\n packageId?: string\n name?: string\n key?: string\n username?: string\n}\n\n/**\n * Clear all data from the database\n */\nexport async function clearDatabase(): Promise {\n const adapter = getAdapter()\n for (const entityType of ENTITY_TYPES) {\n try {\n const result = (await adapter.list(entityType)) as { data: DBALDeleteCandidate[] }\n for (const item of result.data) {\n const id = item.id ?? item.packageId ?? item.name ?? item.key ?? item.username\n if (id !== null && id !== undefined) {\n await adapter.delete(entityType, id)\n }\n }\n } catch {\n // Skip if entity type doesn't exist\n }\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/export/export-database.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/export/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/import/import-database.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":18,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":18,"endColumn":28},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":19,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":19,"endColumn":32},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":20,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":20,"endColumn":33},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":21,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":21,"endColumn":28},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":22,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":22,"endColumn":30},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":23,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":23,"endColumn":32},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":24,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":24,"endColumn":31},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":25,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":25,"endColumn":41},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":26,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":26,"endColumn":39}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":9,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { setAppConfig } from '../../app-config'\nimport { setComments } from '../../comments'\nimport { setComponentConfigs, setComponentHierarchy } from '../../components'\nimport { setLuaScripts } from '../../lua-scripts'\nimport { setPages } from '../../pages'\nimport { setSchemas } from '../../schemas'\nimport type { DatabaseSchema } from '../../types'\nimport { setUsers } from '../../users'\nimport { setWorkflows } from '../../workflows'\n\n/**\n * Import database contents from JSON string\n */\nexport async function importDatabase(jsonData: string): Promise {\n try {\n const data = JSON.parse(jsonData) as Partial\n\n if (data.users !== null && data.users !== undefined) await setUsers(data.users)\n if (data.workflows !== null && data.workflows !== undefined) await setWorkflows(data.workflows)\n if (data.luaScripts !== null && data.luaScripts !== undefined) await setLuaScripts(data.luaScripts)\n if (data.pages !== null && data.pages !== undefined) await setPages(data.pages)\n if (data.schemas !== null && data.schemas !== undefined) await setSchemas(data.schemas)\n if (data.appConfig !== null && data.appConfig !== undefined) await setAppConfig(data.appConfig)\n if (data.comments !== null && data.comments !== undefined) await setComments(data.comments)\n if (data.componentHierarchy !== null && data.componentHierarchy !== undefined) await setComponentHierarchy(data.componentHierarchy)\n if (data.componentConfigs !== null && data.componentConfigs !== undefined) await setComponentConfigs(data.componentConfigs)\n } catch {\n throw new Error('Failed to import database: Invalid JSON')\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/import/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/app/default-app-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/app/seed-app-config.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":7,"column":29,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":7,"endColumn":52}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAppConfig, setAppConfig } from '../../../app-config'\nimport { buildDefaultAppConfig } from './default-app-config'\n\nexport const seedAppConfig = async () => {\n const appConfig = await getAppConfig()\n\n if (appConfig === null || appConfig === undefined) {\n await setAppConfig(buildDefaultAppConfig())\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/css/build-css-classes.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/css/categories/advanced.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/css/categories/base.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/css/categories/experimental.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/css/css-class-utils.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/css/default-css-categories.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/css/seed-css-categories.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/dropdowns/default-dropdown-configs.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/dropdowns/seed-dropdown-configs.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/database-admin/seed-default-data/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/dropdown-configs/crud/add-dropdown-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/dropdown-configs/crud/delete-dropdown-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/dropdown-configs/crud/get-dropdown-configs.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/dropdown-configs/crud/set-dropdown-configs.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/dropdown-configs/crud/update-dropdown-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/dropdown-configs/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/dropdown-configs/types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/error-logs/crud/add-error-log.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":23,"column":17,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":23,"endColumn":40}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport type { ErrorLog } from '../types'\n\n/**\n * Add a single error log entry\n */\nexport async function addErrorLog(log: Omit): Promise {\n const adapter = getAdapter()\n const id = `error_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`\n\n await adapter.create('ErrorLog', {\n id,\n timestamp: BigInt(log.timestamp),\n level: log.level,\n message: log.message,\n stack: log.stack ?? null,\n context: log.context ?? null,\n userId: log.userId ?? null,\n username: log.username ?? null,\n tenantId: log.tenantId ?? null,\n source: log.source ?? null,\n resolved: log.resolved,\n resolvedAt: log.resolvedAt !== null && log.resolvedAt !== undefined ? BigInt(log.resolvedAt) : null,\n resolvedBy: log.resolvedBy ?? null,\n })\n\n return id\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/error-logs/crud/clear-error-logs.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/error-logs/crud/delete-error-log.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/error-logs/crud/get-error-logs.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":49,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":49,"endColumn":30},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":55,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":55,"endColumn":33},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":63,"column":8,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":63,"endColumn":31}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport type { ErrorLog } from '../types'\n\n/**\n * Get all error logs from database\n */\nexport async function getErrorLogs(options?: {\n limit?: number\n level?: string\n resolved?: boolean\n tenantId?: string\n}): Promise {\n const adapter = getAdapter()\n const result = await adapter.list('ErrorLog')\n\n type ErrorLogRecord = {\n id: string\n timestamp: bigint | number\n level: string\n message: string\n stack?: string | null\n context?: string | null\n userId?: string | null\n username?: string | null\n tenantId?: string | null\n source?: string | null\n resolved: boolean\n resolvedAt?: bigint | number | null\n resolvedBy?: string | null\n }\n\n let logs = (result.data as ErrorLogRecord[]).map(log => ({\n id: log.id,\n timestamp: Number(log.timestamp),\n level: log.level as 'error' | 'warning' | 'info',\n message: log.message,\n stack: log.stack ?? undefined,\n context: log.context ?? undefined,\n userId: log.userId ?? undefined,\n username: log.username ?? undefined,\n tenantId: log.tenantId ?? undefined,\n source: log.source ?? undefined,\n resolved: log.resolved,\n resolvedAt: (log.resolvedAt !== null && log.resolvedAt !== undefined) ? Number(log.resolvedAt) : undefined,\n resolvedBy: log.resolvedBy ?? undefined,\n }))\n\n // Apply filters\n if (options?.level !== null && options?.level !== undefined) {\n logs = logs.filter(log => log.level === options.level)\n }\n if (options?.resolved !== undefined) {\n logs = logs.filter(log => log.resolved === options.resolved)\n }\n if (options?.tenantId !== null && options?.tenantId !== undefined) {\n logs = logs.filter(log => log.tenantId === options.tenantId)\n }\n\n // Sort by timestamp descending (newest first)\n logs.sort((a, b) => b.timestamp - a.timestamp)\n\n // Apply limit\n if ((options?.limit !== null && options?.limit !== undefined) && options.limit > 0) {\n logs = logs.slice(0, options.limit)\n }\n\n return logs\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/error-logs/crud/update-error-log.ts","messages":[],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":17,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":17,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[407,410],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[407,410],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/error-logs/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/error-logs/tests/add-error-log.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/error-logs/tests/get-error-logs.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":128,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":128,"endColumn":35}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { beforeEach, describe, expect, it, vi } from 'vitest'\n\nconst mockList = vi.fn()\nconst mockAdapter = { list: mockList }\n\nvi.mock('../../core/dbal-client', () => ({\n getAdapter: () => mockAdapter,\n}))\n\nimport { getErrorLogs } from '../crud/get-error-logs'\n\ndescribe('getErrorLogs', () => {\n beforeEach(() => {\n mockList.mockReset()\n })\n\n it.each([\n {\n name: 'empty array when no logs',\n dbData: [],\n options: undefined,\n expectedLength: 0,\n },\n {\n name: 'all error logs',\n dbData: [\n {\n id: 'error_1',\n timestamp: BigInt(Date.now()),\n level: 'error',\n message: 'Test error',\n stack: 'Error: Test error',\n context: null,\n userId: null,\n username: null,\n tenantId: 'tenant_1',\n source: 'test.ts',\n resolved: false,\n resolvedAt: null,\n resolvedBy: null,\n },\n ],\n options: undefined,\n expectedLength: 1,\n },\n {\n name: 'filtered by level',\n dbData: [\n {\n id: 'error_1',\n timestamp: BigInt(Date.now()),\n level: 'error',\n message: 'Test error',\n stack: null,\n context: null,\n userId: null,\n username: null,\n tenantId: 'tenant_1',\n source: null,\n resolved: false,\n resolvedAt: null,\n resolvedBy: null,\n },\n {\n id: 'warning_1',\n timestamp: BigInt(Date.now()),\n level: 'warning',\n message: 'Test warning',\n stack: null,\n context: null,\n userId: null,\n username: null,\n tenantId: 'tenant_1',\n source: null,\n resolved: false,\n resolvedAt: null,\n resolvedBy: null,\n },\n ],\n options: { level: 'error' },\n expectedLength: 1,\n },\n {\n name: 'filtered by tenantId',\n dbData: [\n {\n id: 'error_1',\n timestamp: BigInt(Date.now()),\n level: 'error',\n message: 'Tenant 1 error',\n stack: null,\n context: null,\n userId: null,\n username: null,\n tenantId: 'tenant_1',\n source: null,\n resolved: false,\n resolvedAt: null,\n resolvedBy: null,\n },\n {\n id: 'error_2',\n timestamp: BigInt(Date.now()),\n level: 'error',\n message: 'Tenant 2 error',\n stack: null,\n context: null,\n userId: null,\n username: null,\n tenantId: 'tenant_2',\n source: null,\n resolved: false,\n resolvedAt: null,\n resolvedBy: null,\n },\n ],\n options: { tenantId: 'tenant_1' },\n expectedLength: 1,\n },\n ])('should return $name', async ({ dbData, options, expectedLength }) => {\n mockList.mockResolvedValue({ data: dbData })\n\n const result = await getErrorLogs(options)\n\n expect(mockList).toHaveBeenCalledWith('ErrorLog')\n expect(result).toHaveLength(expectedLength)\n\n if (options?.tenantId !== null && options?.tenantId !== undefined && result.length > 0) {\n expect(result.every(log => log.tenantId === options.tenantId)).toBe(true)\n }\n })\n})\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/error-logs/types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/app-config/get-app-config.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":14,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":14,"endColumn":59},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":14,"column":24,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":14,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .appConfiguration on an `error` typed value.","line":14,"column":31,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":14,"endColumn":47},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":15,"column":8,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":15,"endColumn":14,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[431,437],"text":"(Boolean(config))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":18,"column":5,"nodeType":"Property","messageId":"anyAssignment","endLine":18,"endColumn":18},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `error` typed value.","line":18,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":18,"endColumn":18},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":19,"column":5,"nodeType":"Property","messageId":"anyAssignment","endLine":19,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .name on an `error` typed value.","line":19,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":19,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `string`.","line":20,"column":25,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":20,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .schemas on an `error` typed value.","line":20,"column":32,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":20,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `string`.","line":21,"column":27,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":21,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .workflows on an `error` typed value.","line":21,"column":34,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":21,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `string`.","line":22,"column":28,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":22,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .luaScripts on an `error` typed value.","line":22,"column":35,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":22,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `string`.","line":23,"column":23,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":23,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .pages on an `error` typed value.","line":23,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":23,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `string`.","line":24,"column":23,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":24,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .theme on an `error` typed value.","line":24,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":24,"endColumn":35}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":18,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Get App Config\n * Retrieves the application configuration from database\n */\n\nimport type { AppConfiguration } from '@/lib/types/level-types'\nimport { prisma } from '@/lib/config/prisma'\n\n/**\n * Get the application configuration\n * @returns AppConfiguration or null if not found\n */\nexport const getAppConfig = async (): Promise => {\n const config = await prisma.appConfiguration.findFirst()\n if (!config) return null\n\n return {\n id: config.id,\n name: config.name,\n schemas: JSON.parse(config.schemas),\n workflows: JSON.parse(config.workflows),\n luaScripts: JSON.parse(config.luaScripts),\n pages: JSON.parse(config.pages),\n theme: JSON.parse(config.theme),\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/app-config/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/app-config/set-app-config.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":14,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":14,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .appConfiguration on an `error` typed value.","line":14,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":14,"endColumn":32},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":15,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":15,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .appConfiguration on an `error` typed value.","line":15,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":15,"endColumn":32}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Set App Config\n * Saves the application configuration to database\n */\n\nimport type { AppConfiguration } from '@/lib/types/level-types'\nimport { prisma } from '@/lib/config/prisma'\n\n/**\n * Set the application configuration\n * @param config - The configuration to save\n */\nexport const setAppConfig = async (config: AppConfiguration): Promise => {\n await prisma.appConfiguration.deleteMany()\n await prisma.appConfiguration.create({\n data: {\n id: config.id,\n name: config.name,\n schemas: JSON.stringify(config.schemas),\n workflows: JSON.stringify(config.workflows),\n luaScripts: JSON.stringify(config.luaScripts),\n pages: JSON.stringify(config.pages),\n theme: JSON.stringify(config.theme),\n },\n })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/comments/crud/add-comment.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":14,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":14,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .comment on an `error` typed value.","line":14,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":14,"endColumn":23}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Add Comment\n * Adds a new comment to database\n */\n\nimport type { Comment } from '@/lib/types/level-types'\nimport { prisma } from '@/lib/config/prisma'\n\n/**\n * Add a new comment\n * @param comment - Comment to add\n */\nexport const addComment = async (comment: Comment): Promise => {\n await prisma.comment.create({\n data: {\n id: comment.id,\n userId: comment.userId,\n content: comment.content,\n createdAt: BigInt(comment.createdAt),\n updatedAt: comment.updatedAt !== null && comment.updatedAt !== undefined ? BigInt(comment.updatedAt) : null,\n parentId: comment.parentId,\n },\n })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/comments/crud/delete-comment.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":13,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":13,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .comment on an `error` typed value.","line":13,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":13,"endColumn":23}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Delete Comment\n * Deletes a comment from database\n */\n\nimport { prisma } from '@/lib/config/prisma'\n\n/**\n * Delete a comment\n * @param commentId - ID of comment to delete\n */\nexport const deleteComment = async (commentId: string): Promise => {\n await prisma.comment.delete({ where: { id: commentId } })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/comments/crud/get-comments.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":14,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":14,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":14,"column":26,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":14,"endColumn":49},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .comment on an `error` typed value.","line":14,"column":33,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":14,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type error.","line":15,"column":3,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":24,"endColumn":6},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":15,"column":10,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":15,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .map on an `error` typed value.","line":15,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":15,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":16,"column":5,"nodeType":"Property","messageId":"anyAssignment","endLine":16,"endColumn":13},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `any` value.","line":16,"column":11,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":16,"endColumn":13},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":17,"column":5,"nodeType":"Property","messageId":"anyAssignment","endLine":17,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .userId on an `any` value.","line":17,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":17,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":18,"column":5,"nodeType":"Property","messageId":"anyAssignment","endLine":18,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .entityType on an `any` value.","line":18,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":18,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":19,"column":5,"nodeType":"Property","messageId":"anyAssignment","endLine":19,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .entityId on an `any` value.","line":19,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":19,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":20,"column":5,"nodeType":"Property","messageId":"anyAssignment","endLine":20,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .content on an `any` value.","line":20,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":20,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .createdAt on an `any` value.","line":21,"column":25,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":21,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .updatedAt on an `any` value.","line":22,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":22,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .updatedAt on an `any` value.","line":22,"column":42,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":22,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .updatedAt on an `any` value.","line":22,"column":77,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":22,"endColumn":86},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":23,"column":5,"nodeType":"Property","messageId":"anyAssignment","endLine":23,"endColumn":80},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .parentId on an `any` value.","line":23,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":23,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .parentId on an `any` value.","line":23,"column":40,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":23,"endColumn":48},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .parentId on an `any` value.","line":23,"column":60,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":23,"endColumn":68}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":24,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Get Comments\n * Retrieves all comments from database\n */\n\nimport type { Comment } from '@/lib/types/level-types'\nimport { prisma } from '@/lib/config/prisma'\n\n/**\n * Get all comments\n * @returns Array of comments\n */\nexport const getComments = async (): Promise => {\n const comments = await prisma.comment.findMany()\n return comments.map(c => ({\n id: c.id,\n userId: c.userId,\n entityType: c.entityType,\n entityId: c.entityId,\n content: c.content,\n createdAt: Number(c.createdAt),\n updatedAt: c.updatedAt !== null && c.updatedAt !== undefined ? Number(c.updatedAt) : undefined,\n parentId: c.parentId !== null && c.parentId !== '' ? c.parentId : undefined,\n }))\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/comments/crud/set-comments.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":14,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":14,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .comment on an `error` typed value.","line":14,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":14,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":16,"column":11,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":16,"endColumn":32},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .comment on an `error` typed value.","line":16,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":16,"endColumn":25}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Set Comments\n * Replaces all comments in database\n */\n\nimport type { Comment } from '@/lib/types/level-types'\nimport { prisma } from '@/lib/config/prisma'\n\n/**\n * Set all comments (replaces existing)\n * @param comments - Array of comments to save\n */\nexport const setComments = async (comments: Comment[]): Promise => {\n await prisma.comment.deleteMany()\n for (const comment of comments) {\n await prisma.comment.create({\n data: {\n id: comment.id,\n userId: comment.userId,\n content: comment.content,\n createdAt: BigInt(comment.createdAt),\n updatedAt: comment.updatedAt !== null && comment.updatedAt !== undefined ? BigInt(comment.updatedAt) : null,\n parentId: comment.parentId,\n },\n })\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/comments/crud/update-comment.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":29,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":29,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .comment on an `error` typed value.","line":29,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":29,"endColumn":23}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Update Comment\n * Updates an existing comment\n */\n\nimport type { Comment } from '@/lib/types/level-types'\nimport { prisma } from '@/lib/config/prisma'\n\ntype CommentUpdateData = {\n content?: string\n updatedAt?: bigint\n}\n\n/**\n * Update a comment\n * @param commentId - ID of comment to update\n * @param updates - Partial comment with updates\n */\nexport const updateComment = async (\n commentId: string,\n updates: Partial\n): Promise => {\n const data: CommentUpdateData = {}\n if (updates.content !== undefined) data.content = updates.content\n if (updates.updatedAt !== undefined && updates.updatedAt !== null) {\n data.updatedAt = BigInt(updates.updatedAt)\n }\n\n await prisma.comment.update({\n where: { id: commentId },\n data,\n })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/comments/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/components/crud/add-component-node.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":14,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":14,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .componentNode on an `error` typed value.","line":14,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":14,"endColumn":29}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Add Component Node\n * Adds a new component node to hierarchy\n */\n\nimport { prisma } from '@/lib/config/prisma'\nimport type { ComponentNode } from '../hierarchy/types'\n\n/**\n * Add a component node\n * @param node - Component node to add\n */\nexport const addComponentNode = async (node: ComponentNode): Promise => {\n await prisma.componentNode.create({\n data: {\n id: node.id,\n type: node.type,\n parentId: node.parentId,\n childIds: JSON.stringify(node.childIds),\n order: node.order,\n pageId: node.pageId,\n },\n })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/components/crud/delete-component-node.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":13,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":13,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .componentNode on an `error` typed value.","line":13,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":13,"endColumn":29}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Delete Component Node\n * Deletes a component node from hierarchy\n */\n\nimport { prisma } from '@/lib/config/prisma'\n\n/**\n * Delete a component node\n * @param nodeId - ID of node to delete\n */\nexport const deleteComponentNode = async (nodeId: string): Promise => {\n await prisma.componentNode.delete({ where: { id: nodeId } })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/components/crud/update-component-node.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":31,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":31,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .componentNode on an `error` typed value.","line":31,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":31,"endColumn":29}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Update Component Node\n * Updates an existing component node\n */\n\nimport { prisma } from '@/lib/config/prisma'\nimport type { ComponentNode } from '../hierarchy/types'\n\n/**\n * Update a component node\n * @param nodeId - ID of node to update\n * @param updates - Partial node with updates\n */\nexport const updateComponentNode = async (\n nodeId: string,\n updates: Partial\n): Promise => {\n const data: Partial<{\n type: string\n parentId: string | null\n childIds: string\n order: number\n pageId: string\n }> = {}\n if (updates.type !== undefined) data.type = updates.type\n if (updates.parentId !== undefined) data.parentId = updates.parentId\n if (updates.childIds !== undefined) data.childIds = JSON.stringify(updates.childIds)\n if (updates.order !== undefined) data.order = updates.order\n if (updates.pageId !== undefined) data.pageId = updates.pageId\n\n await prisma.componentNode.update({\n where: { id: nodeId },\n data,\n })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/components/hierarchy/get-component-configs.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":15,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":15,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":15,"column":25,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":15,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .componentConfig on an `error` typed value.","line":15,"column":32,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":15,"endColumn":47},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Computed name [config.id] resolves to an `error` typed value.","line":18,"column":12,"nodeType":"MemberExpression","messageId":"unsafeComputedMemberAccess","endLine":18,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `error` typed value.","line":18,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":18,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":19,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":19,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `error` typed value.","line":19,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":19,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":20,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":20,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .componentId on an `error` typed value.","line":20,"column":27,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":20,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `string`.","line":21,"column":25,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":21,"endColumn":37},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .props on an `error` typed value.","line":21,"column":32,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":21,"endColumn":37},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `string`.","line":22,"column":26,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":22,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .styles on an `error` typed value.","line":22,"column":33,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":22,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `string`.","line":23,"column":26,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":23,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .events on an `error` typed value.","line":23,"column":33,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":23,"endColumn":39},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .conditionalRendering on an `error` typed value.","line":24,"column":36,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":24,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .conditionalRendering on an `error` typed value.","line":24,"column":76,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":24,"endColumn":96},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `string`.","line":25,"column":22,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":25,"endColumn":49},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .conditionalRendering on an `error` typed value.","line":25,"column":29,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":25,"endColumn":49}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":19,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Get Component Configs\n * Retrieves component configurations from database\n */\n\nimport { prisma } from '@/lib/config/prisma'\nimport type { ComponentConfig } from './types'\nimport type { JsonValue } from '@/types/utility-types'\n\n/**\n * Get all component configs\n * @returns Record of component configs by ID\n */\nexport const getComponentConfigs = async (): Promise> => {\n const configs = await prisma.componentConfig.findMany()\n const result: Record = {}\n for (const config of configs) {\n result[config.id] = {\n id: config.id,\n componentId: config.componentId,\n props: JSON.parse(config.props) as Record,\n styles: JSON.parse(config.styles) as Record,\n events: JSON.parse(config.events) as Record,\n conditionalRendering: config.conditionalRendering !== null && config.conditionalRendering !== ''\n ? JSON.parse(config.conditionalRendering) as { condition: string; luaScriptId?: string }\n : undefined,\n }\n }\n return result\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/components/hierarchy/get-component-hierarchy.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":14,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":14,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":14,"column":23,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":14,"endColumn":52},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .componentNode on an `error` typed value.","line":14,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":14,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Computed name [node.id] resolves to an `error` typed value.","line":17,"column":12,"nodeType":"MemberExpression","messageId":"unsafeComputedMemberAccess","endLine":17,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `error` typed value.","line":17,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":17,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":18,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":18,"endColumn":18},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .id on an `error` typed value.","line":18,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":18,"endColumn":18},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":19,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":19,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .type on an `error` typed value.","line":19,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":19,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":20,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":20,"endColumn":91},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .parentId on an `error` typed value.","line":20,"column":22,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":20,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .parentId on an `error` typed value.","line":20,"column":48,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":20,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .parentId on an `error` typed value.","line":20,"column":71,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":20,"endColumn":79},{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type error typed assigned to a parameter of type `string`.","line":21,"column":28,"nodeType":"MemberExpression","messageId":"unsafeArgument","endLine":21,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .childIds on an `error` typed value.","line":21,"column":33,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":21,"endColumn":41},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":22,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":22,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .order on an `error` typed value.","line":22,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":22,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an error typed value.","line":23,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":23,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .pageId on an `error` typed value.","line":23,"column":20,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":23,"endColumn":26}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":19,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Get Component Hierarchy\n * Retrieves component hierarchy from database\n */\n\nimport { prisma } from '@/lib/config/prisma'\nimport type { ComponentNode } from './types'\n\n/**\n * Get the component hierarchy\n * @returns Record of component nodes by ID\n */\nexport const getComponentHierarchy = async (): Promise> => {\n const nodes = await prisma.componentNode.findMany()\n const result: Record = {}\n for (const node of nodes) {\n result[node.id] = {\n id: node.id,\n type: node.type,\n parentId: node.parentId !== null && node.parentId !== '' ? node.parentId : undefined,\n childIds: JSON.parse(node.childIds) as string[],\n order: node.order,\n pageId: node.pageId,\n }\n }\n return result\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/components/hierarchy/set-component-hierarchy.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":16,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":16,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .componentNode on an `error` typed value.","line":16,"column":16,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":16,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":18,"column":11,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":18,"endColumn":38},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .componentNode on an `error` typed value.","line":18,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":18,"endColumn":31}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Set Component Hierarchy\n * Replaces all component hierarchy in database\n */\n\nimport { prisma } from '@/lib/config/prisma'\nimport type { ComponentNode } from './types'\n\n/**\n * Set the component hierarchy (replaces existing)\n * @param hierarchy - Record of component nodes by ID\n */\nexport const setComponentHierarchy = async (\n hierarchy: Record\n): Promise => {\n await prisma.componentNode.deleteMany()\n for (const node of Object.values(hierarchy)) {\n await prisma.componentNode.create({\n data: {\n id: node.id,\n type: node.type,\n parentId: node.parentId,\n childIds: JSON.stringify(node.childIds),\n order: node.order,\n pageId: node.pageId,\n },\n })\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/functions/components/hierarchy/types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/god-credentials/index.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":10,"column":11,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":10,"endColumn":33},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":36,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":36,"endColumn":25},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":58,"column":11,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":58,"endColumn":33}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../core/dbal-client'\n\n/**\n * Get god credentials expiry timestamp\n */\nexport async function getGodCredentialsExpiry(): Promise {\n const adapter = getAdapter()\n const result = await adapter.list('SystemConfig')\n const config = (result.data as Array<{ key: string; value?: string }>).find((c) => c.key === 'godCredentialsExpiry')\n return (config?.value !== null && config?.value !== undefined) ? Number(config.value) : 0\n}\n\n/**\n * Set god credentials expiry timestamp\n */\nexport async function setGodCredentialsExpiry(timestamp: number): Promise {\n const adapter = getAdapter()\n await adapter.upsert(\n 'SystemConfig',\n 'key',\n 'godCredentialsExpiry',\n { key: 'godCredentialsExpiry', value: String(timestamp) },\n { value: String(timestamp) }\n )\n}\n\n/**\n * Get first login flags\n */\nexport async function getFirstLoginFlags(): Promise> {\n const adapter = getAdapter()\n const result = await adapter.list('User')\n const users = result.data as Array<{ id?: string; firstLogin?: boolean }>\n const flags: Record = {}\n for (const user of users) {\n if (user.id !== null && user.id !== undefined && user.firstLogin !== undefined) {\n flags[user.id] = Boolean(user.firstLogin)\n }\n }\n return flags\n}\n\n/**\n * Set first login flag for a user\n */\nexport async function setFirstLoginFlag(userId: string, flag: boolean): Promise {\n const adapter = getAdapter()\n await adapter.update('User', userId, { firstLogin: flag })\n}\n\n/**\n * Get god credentials expiry duration\n */\nexport async function getGodCredentialsExpiryDuration(): Promise {\n const adapter = getAdapter()\n const result = await adapter.list('SystemConfig')\n const config = (result.data as Array<{ key: string; value?: string }>).find((c) => c.key === 'godCredentialsExpiryDuration')\n return (config?.value !== null && config?.value !== undefined) ? Number(config.value) : 300000 // Default 5 minutes\n}\n\n/**\n * Set god credentials expiry duration\n */\nexport async function setGodCredentialsExpiryDuration(duration: number): Promise {\n const adapter = getAdapter()\n await adapter.upsert(\n 'SystemConfig',\n 'key',\n 'godCredentialsExpiryDuration',\n { key: 'godCredentialsExpiryDuration', value: String(duration) },\n { value: String(duration) }\n )\n}\n\n/**\n * Check if god credentials should be shown\n */\nexport async function shouldShowGodCredentials(): Promise {\n const expiry = await getGodCredentialsExpiry()\n return expiry > Date.now()\n}\n\n/**\n * Reset god credentials expiry\n */\nexport async function resetGodCredentialsExpiry(): Promise {\n const duration = await getGodCredentialsExpiryDuration()\n await setGodCredentialsExpiry(Date.now() + duration)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/hash-password.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/lua-scripts/crud/add-lua-script.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/lua-scripts/crud/delete-lua-script.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/lua-scripts/crud/get-lua-scripts.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/lua-scripts/crud/set-lua-scripts.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/lua-scripts/crud/update-lua-script.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/lua-scripts/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/data/delete-package-data.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/data/delete-package-data.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/data/get/get-package-data.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/data/get/get-package-data.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":12,"column":23,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":12,"endColumn":40}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { type PackageSeedData } from '../../../../packages/core/package-types'\nimport { getAdapter } from '../../../core/dbal-client'\n\n/**\n * Get package data for a specific package\n */\nexport async function getPackageData(packageId: string): Promise {\n const adapter = getAdapter()\n const pkg = (await adapter.findFirst('PackageData', {\n where: { packageId },\n })) as { data: string } | null\n if (pkg === null || pkg === undefined) return {}\n return JSON.parse(pkg.data) as PackageSeedData\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/data/set-package-data.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/data/set-package-data.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/delete-package-data.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/get-installed-packages.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/get-package-data.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/install-package.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/install/crud/actions/toggle-package-enabled.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/install/crud/actions/toggle-package-enabled.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/install/crud/install-package.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/install/crud/install-package.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/install/crud/uninstall-package.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/install/crud/uninstall-package.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/install/getters/get-installed-packages.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/install/getters/get-installed-packages.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/install/getters/set-installed-packages.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/set-package-data.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/toggle-package-enabled.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/packages/uninstall-package.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/pages/crud/add-page.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/pages/crud/add-page.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/pages/crud/delete-page.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/pages/crud/delete-page.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/pages/crud/get-pages.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/pages/crud/get-pages.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/pages/crud/set-pages.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/pages/crud/set-pages.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/pages/crud/update-page.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `Partial`.","line":32,"column":30,"nodeType":"TSAsExpression","messageId":"unsafeArgument","endLine":32,"endColumn":44}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":1,"message":"Unexpected any. Specify a different type.","line":32,"column":41,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":32,"endColumn":44,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[820,823],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[820,823],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { beforeEach, describe, expect, it, vi } from 'vitest'\n\nconst mockUpdate = vi.fn()\nconst mockAdapter = { update: mockUpdate }\n\nvi.mock('../../core/dbal-client', () => ({\n getAdapter: () => mockAdapter,\n}))\n\nimport { updatePage } from './update-page'\n\ndescribe('updatePage', () => {\n beforeEach(() => {\n mockUpdate.mockReset()\n })\n\n it.each([\n {\n name: 'title only',\n pageId: 'page_1',\n updates: { title: 'New Title' },\n },\n {\n name: 'multiple fields',\n pageId: 'page_2',\n updates: { path: '/new-path', requiresAuth: true, requiredRole: 'admin' },\n },\n ])('should update $name', async ({ pageId, updates }) => {\n mockUpdate.mockResolvedValue(undefined)\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await updatePage(pageId, updates as any)\n\n expect(mockUpdate).toHaveBeenCalledWith('PageConfig', pageId, expect.any(Object))\n })\n})\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/pages/crud/update-page.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/pages/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/password/hash-password.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/password/hash-password.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/password/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/password/verify-password.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/password/verify-password.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/power-transfers/crud/add-power-transfer-request.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/power-transfers/crud/delete-power-transfer-request.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/power-transfers/crud/get-power-transfer-requests.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/power-transfers/crud/set-power-transfer-requests.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/power-transfers/crud/update-power-transfer-request.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/power-transfers/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/schemas/crud/add-schema.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `ModelSchema`.","line":36,"column":21,"nodeType":"TSAsExpression","messageId":"unsafeArgument","endLine":36,"endColumn":34}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":1,"message":"Unexpected any. Specify a different type.","line":36,"column":31,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":36,"endColumn":34,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[856,859],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[856,859],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { beforeEach, describe, expect, it, vi } from 'vitest'\n\nconst mockCreate = vi.fn()\nconst mockAdapter = { create: mockCreate }\n\nvi.mock('../../core/dbal-client', () => ({\n getAdapter: () => mockAdapter,\n}))\n\nimport { addSchema } from './add-schema'\n\ndescribe('addSchema', () => {\n beforeEach(() => {\n mockCreate.mockReset()\n })\n\n it.each([\n {\n name: 'basic schema',\n schema: { name: 'User', fields: [{ name: 'id', type: 'string' }] },\n },\n {\n name: 'full schema',\n schema: {\n name: 'Post',\n label: 'Blog Post',\n labelPlural: 'Posts',\n fields: [],\n listDisplay: ['title'],\n },\n },\n ])('should add $name', async ({ schema }) => {\n mockCreate.mockResolvedValue(undefined)\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await addSchema(schema as any)\n\n expect(mockCreate).toHaveBeenCalledWith(\n 'ModelSchema',\n expect.objectContaining({\n name: schema.name,\n })\n )\n })\n})\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/schemas/crud/add-schema.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/schemas/crud/delete-schema.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/schemas/crud/delete-schema.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/schemas/crud/get-schemas.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/schemas/crud/get-schemas.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/schemas/crud/set-schemas.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `ModelSchema[]`.","line":27,"column":22,"nodeType":"TSAsExpression","messageId":"unsafeArgument","endLine":27,"endColumn":58}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":1,"message":"Unexpected any. Specify a different type.","line":27,"column":55,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":27,"endColumn":58,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[803,806],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[803,806],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { beforeEach, describe, expect, it, vi } from 'vitest'\n\nconst mockList = vi.fn()\nconst mockDelete = vi.fn()\nconst mockCreate = vi.fn()\nconst mockAdapter = { list: mockList, delete: mockDelete, create: mockCreate }\n\nvi.mock('../../core/dbal-client', () => ({\n getAdapter: () => mockAdapter,\n}))\n\nimport { setSchemas } from './set-schemas'\n\ndescribe('setSchemas', () => {\n beforeEach(() => {\n mockList.mockReset()\n mockDelete.mockReset()\n mockCreate.mockReset()\n })\n\n it('should replace all schemas', async () => {\n mockList.mockResolvedValue({ data: [{ name: 'old' }] })\n mockDelete.mockResolvedValue(undefined)\n mockCreate.mockResolvedValue(undefined)\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await setSchemas([{ name: 'New', fields: [] }] as any)\n\n expect(mockDelete).toHaveBeenCalledTimes(1)\n expect(mockCreate).toHaveBeenCalledTimes(1)\n })\n})\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/schemas/crud/set-schemas.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/schemas/crud/update-schema.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `Partial`.","line":24,"column":30,"nodeType":"TSAsExpression","messageId":"unsafeArgument","endLine":24,"endColumn":44}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":1,"message":"Unexpected any. Specify a different type.","line":24,"column":41,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":24,"endColumn":44,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[711,714],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[711,714],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { beforeEach, describe, expect, it, vi } from 'vitest'\n\nconst mockUpdate = vi.fn()\nconst mockAdapter = { update: mockUpdate }\n\nvi.mock('../../core/dbal-client', () => ({\n getAdapter: () => mockAdapter,\n}))\n\nimport { updateSchema } from './update-schema'\n\ndescribe('updateSchema', () => {\n beforeEach(() => {\n mockUpdate.mockReset()\n })\n\n it.each([\n { name: 'User', updates: { label: 'User Account' } },\n { name: 'Post', updates: { fields: [{ name: 'title', type: 'string' }] } },\n ])('should update $name', async ({ name, updates }) => {\n mockUpdate.mockResolvedValue(undefined)\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await updateSchema(name, updates as any)\n\n expect(mockUpdate).toHaveBeenCalledWith('ModelSchema', name, expect.any(Object))\n })\n})\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/schemas/crud/update-schema.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/schemas/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/create-session.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/crud/create/create-session.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/crud/create/create-session.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/crud/delete/delete-session-by-token.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/crud/delete/delete-session-by-token.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":14,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":14,"endColumn":23}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../../core/dbal-client'\n\ntype DBALSessionRecord = {\n id: string\n}\n\nexport async function deleteSessionByToken(token: string): Promise {\n const adapter = getAdapter()\n const result = (await adapter.list('Session', { filter: { token } })) as {\n data: DBALSessionRecord[]\n }\n if (result.data.length === 0) return false\n const session = result.data[0]\n if (session === null || session === undefined) return false\n await adapter.delete('Session', session.id)\n return true\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/crud/delete/delete-session.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/crud/delete/delete-session.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/crud/update-session.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/crud/update-session.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":11,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":11,"endColumn":29}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport { mapSessionRecord, type SessionRecord } from '../map-session-record'\nimport type { Session, UpdateSessionInput } from '../types'\n\nexport async function updateSession(\n sessionId: string,\n input: UpdateSessionInput\n): Promise {\n const adapter = getAdapter()\n const record = await adapter.update('Session', sessionId, {\n ...(input.token !== null && input.token !== undefined ? { token: input.token } : {}),\n ...(input.expiresAt !== undefined ? { expiresAt: BigInt(input.expiresAt) } : {}),\n ...(input.lastActivity !== undefined ? { lastActivity: BigInt(input.lastActivity) } : {}),\n })\n return mapSessionRecord(record as SessionRecord)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/delete-session-by-token.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/delete-session.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/get-session-by-id.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/get-session-by-token.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/getters/get-session-by-id.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/getters/get-session-by-token.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/getters/get-session-by-token.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/getters/list-sessions.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/getters/list-sessions.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":7,"column":18,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":7,"endColumn":42}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":12,"column":36,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":12,"endColumn":39,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[578,581],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[578,581],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport { mapSessionRecord } from '../map-session-record'\nimport type { ListSessionsOptions, Session } from '../types'\n\nexport async function listSessions(options?: ListSessionsOptions): Promise {\n const adapter = getAdapter()\n const result = options?.userId !== null && options?.userId !== undefined\n ? await adapter.list('Session', { filter: { userId: options.userId } })\n : await adapter.list('Session')\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sessions = (result.data as any[]).map(mapSessionRecord)\n\n if (options?.includeExpired === true) {\n return sessions\n }\n\n const now = Date.now()\n return sessions.filter(session => session.expiresAt > now)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/map-session-record.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/sessions/update-session.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/smtp-config/get-smtp-config.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":13,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":13,"endColumn":22}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { SMTPConfig } from '../password'\nimport { getAdapter } from '../core/dbal-client'\n\ntype DBALSMTPConfig = SMTPConfig\n\n/**\n * Get SMTP configuration\n */\nexport async function getSMTPConfig(): Promise {\n const adapter = getAdapter()\n const result = (await adapter.list('SMTPConfig')) as { data: DBALSMTPConfig[] }\n const config = result.data[0]\n if (config === null || config === undefined) return null\n\n return {\n host: config.host,\n port: config.port,\n secure: config.secure,\n username: config.username,\n password: config.password,\n fromEmail: config.fromEmail,\n fromName: config.fromName,\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/smtp-config/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/smtp-config/set-smtp-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/system-config/get-system-config-value.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/system-config/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/tenants/crud/add-tenant.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/tenants/crud/delete-tenant.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/tenants/crud/get-tenants.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/tenants/crud/set-tenants.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/tenants/crud/update-tenant.ts","messages":[],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":10,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":10,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[365,368],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[365,368],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/tenants/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/types/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/add-user.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/crud/add/add-user.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/crud/add/add-user.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/crud/delete-user.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/crud/delete-user.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/crud/update-user.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/crud/update-user.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/get-user-by-id.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/get-user-first-login-flag.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/get-users.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/getters/get-user-by-id.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/getters/get-user-by-id.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":13,"column":18,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":13,"endColumn":44}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport type { User } from '@/lib/types/level-types'\nimport { mapUserRecord } from '../map-user-record'\n\n/**\n * Get a user by ID from database\n */\nexport async function getUserById(\n userId: string,\n options?: { tenantId?: string }\n): Promise {\n const adapter = getAdapter()\n const record = options?.tenantId !== null && options?.tenantId !== undefined\n ? await adapter.findFirst('User', { where: { id: userId, tenantId: options.tenantId } })\n : await adapter.read('User', userId)\n\n if (record === null || record === undefined) return null\n\n return mapUserRecord(record as Record)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/getters/get-user-first-login-flag.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/getters/get-users.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/getters/get-users.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":14,"column":18,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":14,"endColumn":38}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { getAdapter } from '../../core/dbal-client'\nimport type { User } from '@/lib/types/level-types'\nimport { mapUserRecord } from '../map-user-record'\n\nexport type GetUsersOptions = { tenantId: string } | { scope: 'all' }\n\n/**\n * Get users from database.\n * Requires explicit scope to avoid accidental cross-tenant access.\n */\nexport async function getUsers(options: GetUsersOptions): Promise {\n const adapter = getAdapter()\n const listOptions = 'tenantId' in options ? { filter: { tenantId: options.tenantId } } : undefined\n const result = listOptions !== null && listOptions !== undefined ? await adapter.list('User', listOptions) : await adapter.list('User')\n return (result.data as Record[]).map(user => mapUserRecord(user))\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/map-user-record.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/set-users.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/set-users.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/super-god/get-super-god.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/super-god/get-super-god.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/super-god/transfer-super-god-power.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":11,"column":69,"nodeType":"CallExpression","messageId":"unsafeReturn","endLine":11,"endColumn":96}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { beforeEach, describe, expect, it, vi } from 'vitest'\n\n// Mock the get-dbal module to prevent server-only imports\nvi.mock('@/lib/dbal/database-dbal/core/get-dbal.server', () => ({\n getDBAL: vi.fn(),\n}))\n\nconst mockDbalUpdate = vi.fn()\n\nvi.mock('@/lib/dbal/database-dbal/users/dbal-update-user.server', () => ({\n dbalUpdateUser: (id: string, payload: Record) => mockDbalUpdate(id, payload),\n}))\n\nimport { transferSuperGodPower } from './transfer-super-god-power'\n\ndescribe('transferSuperGodPower', () => {\n beforeEach(() => {\n mockDbalUpdate.mockReset()\n })\n\n it.each([\n { fromUserId: 'user_sg', toUserId: 'user_god' },\n { fromUserId: 'owner_1', toUserId: 'admin_2' },\n ])('updates both users when transferring power', async ({ fromUserId, toUserId }) => {\n mockDbalUpdate.mockResolvedValue({ id: fromUserId })\n\n await transferSuperGodPower(fromUserId, toUserId)\n\n expect(mockDbalUpdate).toHaveBeenCalledTimes(2)\n expect(mockDbalUpdate).toHaveBeenNthCalledWith(1, fromUserId, {\n isInstanceOwner: false,\n role: 'god',\n })\n expect(mockDbalUpdate).toHaveBeenNthCalledWith(2, toUserId, {\n isInstanceOwner: true,\n role: 'supergod',\n })\n })\n\n it('propagates errors from the DBAL client', async () => {\n mockDbalUpdate.mockRejectedValue(new Error('Transfer failed'))\n\n await expect(transferSuperGodPower('u1', 'u2')).rejects.toThrow('Transfer failed')\n })\n})\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/users/super-god/transfer-super-god-power.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/verify-password.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/workflows/crud/add-workflow.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-argument","severity":1,"message":"Unsafe argument of type `any` assigned to a parameter of type `Workflow`.","line":37,"column":23,"nodeType":"TSAsExpression","messageId":"unsafeArgument","endLine":37,"endColumn":38}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":1,"message":"Unexpected any. Specify a different type.","line":37,"column":35,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":37,"endColumn":38,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[903,906],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[903,906],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { beforeEach, describe, expect, it, vi } from 'vitest'\n\nconst mockCreate = vi.fn()\nconst mockAdapter = { create: mockCreate }\n\nvi.mock('../../core/dbal-client', () => ({\n getAdapter: () => mockAdapter,\n}))\n\nimport { addWorkflow } from './add-workflow'\n\ndescribe('addWorkflow', () => {\n beforeEach(() => {\n mockCreate.mockReset()\n })\n\n it.each([\n {\n name: 'basic workflow',\n workflow: { id: 'w1', name: 'Test', nodes: [], edges: [], enabled: true },\n },\n {\n name: 'workflow with description',\n workflow: {\n id: 'w2',\n name: 'Process',\n description: 'A workflow',\n nodes: [{}],\n edges: [],\n enabled: false,\n },\n },\n ])('should add $name', async ({ workflow }) => {\n mockCreate.mockResolvedValue(undefined)\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n await addWorkflow(workflow as any)\n\n expect(mockCreate).toHaveBeenCalledWith(\n 'Workflow',\n expect.objectContaining({\n id: workflow.id,\n name: workflow.name,\n enabled: workflow.enabled,\n })\n )\n })\n})\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/workflows/crud/add-workflow.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/workflows/crud/delete-workflow.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/workflows/crud/delete-workflow.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/workflows/crud/get-workflows.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/workflows/crud/get-workflows.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/workflows/crud/set-workflows.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/workflows/crud/set-workflows.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/workflows/crud/update-workflow.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/workflows/crud/update-workflow.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/db/workflows/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal-client/adapter/close-adapter.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal-client/adapter/get-adapter.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":12,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":12,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":12,"column":36,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":12,"endColumn":56},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":13,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":13,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[471,476],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":14,"column":18,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":14,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .create on an `any` value.","line":14,"column":24,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":14,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":19,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":19,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":19,"column":35,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":19,"endColumn":55},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":20,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":20,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[769,774],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":21,"column":18,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":21,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .findUnique on an `any` value.","line":21,"column":24,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":21,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":26,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":26,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":26,"column":35,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":26,"endColumn":55},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":27,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":27,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[1081,1086],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":28,"column":18,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":28,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .findUnique on an `any` value.","line":28,"column":24,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":28,"endColumn":34},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":33,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":33,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":33,"column":35,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":33,"endColumn":55},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":34,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":34,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[1422,1427],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":35,"column":18,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":35,"endColumn":33},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .findFirst on an `any` value.","line":35,"column":24,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":35,"endColumn":33},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":40,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":40,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":40,"column":35,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":40,"endColumn":55},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":41,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":41,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[1745,1750],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":43,"column":19,"nodeType":"ChainExpression","messageId":"conditionErrorNullableObject","endLine":43,"endColumn":34,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[1820,1835],"text":"((options?.filter) != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":43,"column":35,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":43,"endColumn":37,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[1836,1838],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":44,"column":21,"nodeType":"ChainExpression","messageId":"conditionErrorNullableString","endLine":44,"endColumn":37,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[1862,1878],"text":"((options?.orderBy) != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[1862,1878],"text":"((options?.orderBy) ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[1862,1878],"text":"(Boolean((options?.orderBy)))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected value in conditional. A boolean expression is required.","line":44,"column":61,"nodeType":"MemberExpression","messageId":"conditionErrorOther","endLine":44,"endColumn":83},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":44,"column":84,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":44,"endColumn":86,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[1925,1927],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe array destructuring of a tuple element with an `any` value.","line":46,"column":12,"nodeType":"Identifier","messageId":"unsafeArrayPatternFromTuple","endLine":46,"endColumn":16},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe array destructuring of a tuple element with an `any` value.","line":46,"column":18,"nodeType":"Identifier","messageId":"unsafeArrayPatternFromTuple","endLine":46,"endColumn":23},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":47,"column":7,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":47,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .findMany on an `any` value.","line":47,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":47,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":53,"column":7,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":53,"endColumn":18},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .count on an `any` value.","line":53,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":53,"endColumn":18},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":57,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":57,"endColumn":11},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":58,"column":7,"nodeType":"Property","messageId":"anyAssignment","endLine":58,"endColumn":12},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable number value in conditional. Please handle the nullish/zero/NaN cases explicitly.","line":59,"column":16,"nodeType":"ChainExpression","messageId":"conditionErrorNullableNumber","endLine":59,"endColumn":30,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[2220,2234],"text":"((options?.limit) != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultZero","fix":{"range":[2220,2234],"text":"((options?.limit) ?? 0)"},"desc":"Explicitly treat nullish value the same as 0 (`value ?? 0`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[2220,2234],"text":"(Boolean((options?.limit)))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable number value in conditional. Please handle the nullish/zero/NaN cases explicitly.","line":59,"column":34,"nodeType":"MemberExpression","messageId":"conditionErrorNullableNumber","endLine":59,"endColumn":48,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[2238,2252],"text":"(options.offset != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultZero","fix":{"range":[2238,2252],"text":"(options.offset ?? 0)"},"desc":"Explicitly treat nullish value the same as 0 (`value ?? 0`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[2238,2252],"text":"(Boolean(options.offset))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":59,"column":49,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":59,"endColumn":51,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[2253,2255],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .length on an `any` value.","line":59,"column":62,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":59,"endColumn":68},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":65,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":65,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":65,"column":35,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":65,"endColumn":55},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":66,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":66,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[2536,2541],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":67,"column":18,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":67,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .update on an `any` value.","line":67,"column":24,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":67,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":78,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":78,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":78,"column":35,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":78,"endColumn":55},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":79,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":79,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[3087,3092],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":83,"column":20,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":83,"endColumn":32},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .upsert on an `any` value.","line":83,"column":26,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":83,"endColumn":32},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":91,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":91,"endColumn":28},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":94,"column":9,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":94,"endColumn":28},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":98,"column":18,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":98,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .upsert on an `any` value.","line":98,"column":24,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":98,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":107,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":107,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":107,"column":35,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":107,"endColumn":55},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":108,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":108,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[4078,4083],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":110,"column":13,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":110,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .delete on an `any` value.","line":110,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":110,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":119,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":119,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":119,"column":35,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":119,"endColumn":55},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":120,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":120,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[4468,4473],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":121,"column":11,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":121,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .createMany on an `any` value.","line":121,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":121,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":127,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":127,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":127,"column":35,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":127,"endColumn":55},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":128,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":128,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[4824,4829],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":131,"column":21,"nodeType":"CallExpression","messageId":"unsafeReturn","endLine":131,"endColumn":58},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":131,"column":21,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":131,"endColumn":33},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .update on an `any` value.","line":131,"column":27,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":131,"endColumn":33},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any[]`.","line":133,"column":5,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":133,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":138,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":138,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":138,"column":35,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":138,"endColumn":55},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":139,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":139,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[5219,5224],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":140,"column":11,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":140,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .deleteMany on an `any` value.","line":140,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":140,"endColumn":27},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":149,"column":11,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":149,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access [entity.toLowerCase()] on an `any` value.","line":149,"column":35,"nodeType":"CallExpression","messageId":"unsafeMemberExpression","endLine":149,"endColumn":55},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":150,"column":10,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":150,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[5717,5722],"text":"(Boolean(model))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":151,"column":5,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":151,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":151,"column":18,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":151,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .count on an `any` value.","line":151,"column":24,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":151,"endColumn":29},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":151,"column":39,"nodeType":"Identifier","messageId":"conditionErrorNullableObject","endLine":151,"endColumn":45,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[5807,5813],"text":"(filter != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":151,"column":46,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":151,"endColumn":48,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[5814,5816],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type error.","line":155,"column":5,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":155,"endColumn":59},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":155,"column":18,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":155,"endColumn":37},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .$transaction on an `error` typed value.","line":155,"column":25,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":155,"endColumn":37},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `error` type typed value.","line":159,"column":11,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":159,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .$disconnect on an `error` typed value.","line":159,"column":18,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":159,"endColumn":29},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??=`) instead of an assignment expression, as it is simpler to read.","line":166,"column":3,"nodeType":"IfStatement","messageId":"preferNullishOverAssignment","endLine":168,"endColumn":4,"suggestions":[{"messageId":"suggestNullish","data":{"equals":"="},"fix":{"range":[6128,6181],"text":"adapter ??= new PrismaAdapter();"},"desc":"Fix to nullish coalescing operator (`??=`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":166,"column":8,"nodeType":"Identifier","messageId":"conditionErrorNullableObject","endLine":166,"endColumn":15,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[6132,6140],"text":"adapter == null"},"desc":"Change condition to check for null/undefined (`value != null`)"}]}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":12,"column":31,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":12,"endColumn":34,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[435,438],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[435,438],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":19,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":19,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[733,736],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[733,736],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":26,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":26,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[1045,1048],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[1045,1048],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":33,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":33,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[1386,1389],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[1386,1389],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":40,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":40,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[1709,1712],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[1709,1712],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":65,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":65,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[2500,2503],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[2500,2503],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":78,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":78,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[3051,3054],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[3051,3054],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":107,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":107,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[4042,4045],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[4042,4045],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":119,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":119,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[4432,4435],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[4432,4435],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":127,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":127,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[4788,4791],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[4788,4791],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":138,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":138,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[5183,5186],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[5183,5186],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":149,"column":30,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":149,"endColumn":33,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[5681,5684],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[5681,5684],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":91,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Get the current DBAL adapter instance\n */\n\nimport { prisma } from '../../config/prisma'\nimport type { DBALAdapter, ListOptions, ListResult } from '../types'\n\n// Simple Prisma-based adapter implementation\nclass PrismaAdapter implements DBALAdapter {\n async create(entity: string, data: Record): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n return await model.create({ data })\n }\n\n async get(entity: string, id: string | number): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n return await model.findUnique({ where: { id } })\n }\n\n async read(entity: string, id: string | number): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n return await model.findUnique({ where: { id } })\n }\n\n async findFirst(entity: string, options: { where: Record }): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n return await model.findFirst({ where: options.where })\n }\n\n async list(entity: string, options?: ListOptions): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n \n const where = options?.filter || {}\n const orderBy = options?.orderBy ? { [options.orderBy]: options.orderDirection || 'asc' } : undefined\n \n const [data, total] = await Promise.all([\n model.findMany({\n where,\n orderBy,\n take: options?.limit,\n skip: options?.offset,\n }),\n model.count({ where }),\n ])\n \n return {\n data,\n total,\n hasMore: options?.limit ? (options.offset || 0) + data.length < total : false,\n }\n }\n\n async update(entity: string, id: string | number, data: Record): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n return await model.update({ where: { id }, data })\n }\n\n async upsert(\n entity: string,\n uniqueFieldOrOptions: string | { where: Record; update: Record; create: Record },\n uniqueValue?: unknown,\n createData?: Record,\n updateData?: Record\n ): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n \n // Handle options object form\n if (typeof uniqueFieldOrOptions === 'object') {\n return await model.upsert({\n where: uniqueFieldOrOptions.where,\n create: uniqueFieldOrOptions.create,\n update: uniqueFieldOrOptions.update,\n })\n }\n \n // Handle 5-parameter form - validate data is present\n if (createData === null || createData === undefined) {\n throw new Error('createData is required for upsert')\n }\n if (updateData === null || updateData === undefined) {\n throw new Error('updateData is required for upsert')\n }\n\n return await model.upsert({\n where: { [uniqueFieldOrOptions]: uniqueValue },\n create: createData,\n update: updateData,\n })\n }\n\n async delete(entity: string, id: string | number): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n try {\n await model.delete({ where: { id } })\n return true\n } catch {\n return false\n }\n }\n\n async createMany(entity: string, data: Record[]): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n await model.createMany({ data })\n return data\n }\n\n async updateMany(entity: string, ids: (string | number)[], data: Record): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n \n const results = await Promise.all(\n ids.map(id => model.update({ where: { id }, data }))\n )\n return results\n }\n\n async deleteMany(entity: string, ids: (string | number)[]): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n await model.deleteMany({ where: { id: { in: ids } } })\n }\n\n async query(entity: string, filter: Record, options?: ListOptions): Promise {\n return this.list(entity, { ...options, filter })\n }\n\n async count(entity: string, filter?: Record): Promise {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const model = (prisma as any)[entity.toLowerCase()]\n if (!model) throw new Error(`Unknown entity: ${entity}`)\n return await model.count({ where: filter || {} })\n }\n\n async transaction(fn: (adapter: DBALAdapter) => Promise): Promise {\n return await prisma.$transaction(async () => fn(this))\n }\n\n async close(): Promise {\n await prisma.$disconnect()\n }\n}\n\nlet adapter: DBALAdapter | null = null\n\nexport function getAdapter(): DBALAdapter {\n if (!adapter) {\n adapter = new PrismaAdapter()\n }\n return adapter\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal-client/types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/database-dbal.server.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-client.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/DbalIntegrationUtils.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/blob-delete.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":5,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":5,"endColumn":24,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[228,244],"text":"(Boolean(this.blobStorage))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":5,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":5,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":6,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":6,"endColumn":32},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":6,"column":14,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":6,"endColumn":25}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":40,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":43,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[186,189],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[186,189],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function blobDelete(this: any, key: string): Promise {\n if (!this.blobStorage) throw new Error('DBAL not initialized')\n await this.blobStorage.delete(key)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/blob-download.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'blobDownload' has no 'await' expression.","line":4,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":4,"endColumn":35,"suggestions":[{"messageId":"removeAsync","fix":{"range":[154,222],"text":"function blobDownload(this: any, key: string): Buffer"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":5,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":5,"endColumn":24,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[232,248],"text":"(Boolean(this.blobStorage))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":5,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":5,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":6,"column":3,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":6,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":6,"column":10,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":6,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":6,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":6,"endColumn":26}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":42,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":45,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[188,191],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[188,191],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function blobDownload(this: any, key: string): Promise {\n if (!this.blobStorage) throw new Error('DBAL not initialized')\n return this.blobStorage.download(key)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/blob-get-metadata.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":5,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":5,"endColumn":24,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[251,267],"text":"(Boolean(this.blobStorage))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":5,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":5,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":6,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":6,"endColumn":59},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":6,"column":26,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":6,"endColumn":54},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":6,"column":31,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":6,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":7,"column":3,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":7,"endColumn":39},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":7,"column":10,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":7,"endColumn":33,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[377,400],"text":"(Boolean(metadata.customMetadata))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .customMetadata on an `any` value.","line":7,"column":19,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":7,"endColumn":33},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":7,"column":34,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":7,"endColumn":36,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[401,403],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":45,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":48,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[191,194],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[191,194],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":9,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function blobGetMetadata(this: any, key: string): Promise> {\n if (!this.blobStorage) throw new Error('DBAL not initialized')\n const metadata = await this.blobStorage.getMetadata(key)\n return metadata.customMetadata || {}\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/blob-list.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":5,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":5,"endColumn":24,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[234,250],"text":"(Boolean(this.blobStorage))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":5,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":5,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":6,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":6,"endColumn":57},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":6,"column":24,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":6,"endColumn":45},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":6,"column":29,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":6,"endColumn":40},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":8,"column":3,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":8,"endColumn":51},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":8,"column":10,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":8,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .items on an `any` value.","line":8,"column":17,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":8,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":8,"column":42,"nodeType":"MemberExpression","messageId":"unsafeReturn","endLine":8,"endColumn":50},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .key on an `any` value.","line":8,"column":47,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":8,"endColumn":50}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":38,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":41,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[184,187],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[184,187],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]},{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":8,"column":34,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":8,"endColumn":37,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[447,450],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[447,450],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":10,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function blobList(this: any, prefix?: string): Promise {\n if (!this.blobStorage) throw new Error('DBAL not initialized')\n const result = await this.blobStorage.list({ prefix })\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return result.items.map((item: any) => item.key)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/blob-upload.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":10,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":10,"endColumn":24,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[316,332],"text":"(Boolean(this.blobStorage))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":10,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":10,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":11,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":11,"endColumn":32},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":11,"column":14,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":11,"endColumn":25}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":5,"column":40,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":5,"endColumn":43,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[205,208],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[205,208],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// Blob operations\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function blobUpload(this: any,\n key: string,\n data: Buffer | Uint8Array,\n metadata?: Record\n): Promise {\n if (!this.blobStorage) throw new Error('DBAL not initialized')\n await this.blobStorage.upload(key, data as Buffer, metadata)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/create-tenant.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'createTenant' has no 'await' expression.","line":10,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":10,"endColumn":35,"suggestions":[{"messageId":"removeAsync","fix":{"range":[247,335],"text":"function createTenant(this: any, id: string, limits?: TenantLimits): void"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":11,"column":3,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":11,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tenants on an `any` value.","line":11,"column":8,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":11,"endColumn":15},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":11,"column":34,"nodeType":"Identifier","messageId":"conditionErrorNullableObject","endLine":11,"endColumn":40,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[371,377],"text":"(limits != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":11,"column":41,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":11,"endColumn":43,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[378,380],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":10,"column":42,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":10,"endColumn":45,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[281,284],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[281,284],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":5,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\ninterface TenantLimits {\n maxStorage?: number\n maxUsers?: number\n maxApiCalls?: number\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function createTenant(this: any, id: string, limits?: TenantLimits): Promise {\n this.tenants.set(id, { limits: limits || {} })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/delete.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'blobDeleteDuplicate' has no 'await' expression.","line":4,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":4,"endColumn":42,"suggestions":[{"messageId":"removeAsync","fix":{"range":[154,227],"text":"function blobDeleteDuplicate(this: any, key: string): void"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":5,"column":3,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":5,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobs on an `any` value.","line":5,"column":8,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":5,"endColumn":13}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":49,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":52,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[195,198],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[195,198],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function blobDeleteDuplicate(this: any, key: string): Promise {\n this.blobs.delete(key)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/download.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'download' has no 'await' expression.","line":4,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":4,"endColumn":31,"suggestions":[{"messageId":"removeAsync","fix":{"range":[154,218],"text":"function download(this: any, key: string): Buffer"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":5,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":5,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":5,"column":16,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":5,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobs on an `any` value.","line":5,"column":21,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":5,"endColumn":26},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":6,"column":8,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":6,"endColumn":12,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[263,267],"text":"(Boolean(blob))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":7,"column":3,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":7,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .data on an `any` value.","line":7,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":7,"endColumn":19}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":38,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":41,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[184,187],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[184,187],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":7,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function download(this: any, key: string): Promise {\n const blob = this.blobs.get(key)\n if (!blob) throw new Error(`Blob not found: ${key}`)\n return blob.data\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/get-blob-storage.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":6,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":6,"endColumn":24,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[271,287],"text":"(Boolean(this.blobStorage))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":6,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":6,"endColumn":24},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":9,"column":3,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":9,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":9,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":9,"endColumn":26}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":5,"column":38,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":5,"endColumn":41,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[244,247],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[244,247],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\nimport type { BlobStorage } from '@/dbal/blob/blob-storage'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getBlobStorage(this: any): BlobStorage {\n if (!this.blobStorage) {\n throw new Error('DBAL not initialized. Call initialize() first.')\n }\n return this.blobStorage\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/get-client.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":8,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorNullableObject","endLine":8,"endColumn":19,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[208,220],"text":"this.client == null"},"desc":"Change condition to check for null/undefined (`value != null`)"}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\ninterface DBALClientState {\n client?: _DBALClient\n}\n\nexport function getClient(this: DBALClientState): _DBALClient {\n if (!this.client) {\n throw new Error('DBAL not initialized. Call initialize() first.')\n }\n return this.client\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/get-instance.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/get-k-v-store.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":6,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":6,"endColumn":20,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[255,267],"text":"(Boolean(this.kvStore))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .kvStore on an `any` value.","line":6,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":6,"endColumn":20},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":9,"column":3,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":9,"endColumn":22},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .kvStore on an `any` value.","line":9,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":9,"endColumn":22}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":5,"column":34,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":5,"endColumn":37,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[232,235],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[232,235],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\nimport type { KVStore } from '@/dbal/core/kv/types'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function getKVStore(this: any): KVStore {\n if (!this.kvStore) {\n throw new Error('DBAL not initialized. Call initialize() first.')\n }\n return this.kvStore\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/get-key.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/get-metadata.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'getMetadata' has no 'await' expression.","line":4,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":4,"endColumn":34,"suggestions":[{"messageId":"removeAsync","fix":{"range":[154,261],"text":"function getMetadata(this: any,\n key: string\n): { customMetadata?: Record }"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":7,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":7,"endColumn":35},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":7,"column":16,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":7,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobs on an `any` value.","line":7,"column":21,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":7,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":8,"column":12,"nodeType":"Property","messageId":"anyAssignment","endLine":8,"endColumn":42},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .metadata on an `any` value.","line":8,"column":34,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":8,"endColumn":42}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":41,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":44,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[187,190],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[187,190],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function getMetadata(this: any,\n key: string\n): Promise<{ customMetadata?: Record }> {\n const blob = this.blobs.get(key)\n return { customMetadata: blob?.metadata }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/get-tenant-context.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'getTenantContext' has no 'await' expression.","line":8,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":8,"endColumn":39,"suggestions":[{"messageId":"removeAsync","fix":{"range":[225,349],"text":"function getTenantContext(\n this: TenantStore,\n tenantId: string,\n _userId: string\n): TenantContext | null"},"desc":"Remove 'async'."}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\nimport type { TenantContext } from '@/dbal/core/foundation/tenant-context'\n\ninterface TenantStore {\n tenants: Map\n}\n\nexport async function getTenantContext(\n this: TenantStore,\n tenantId: string,\n _userId: string\n): Promise {\n if (!this.tenants.has(tenantId)) {\n return null\n }\n return {\n tenantId,\n canRead: (_resource: string) => true,\n canWrite: (_resource: string) => true,\n canDelete: (_resource: string) => true,\n canUploadBlob: (_sizeBytes: number) => true,\n canCreateRecord: () => true,\n canAddToList: (_additionalItems: number) => true,\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/get-tenant-manager.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":9,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":9,"endColumn":26,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[299,317],"text":"(Boolean(this.tenantManager))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\ninterface DBALIntegrationContext {\n tenantManager?: unknown\n}\n\n// TenantManager is not yet exported from DBAL, using unknown for now\nexport function getTenantManager(this: DBALIntegrationContext): unknown {\n if (!this.tenantManager) {\n throw new Error('DBAL not initialized. Call initialize() first.')\n }\n return this.tenantManager\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/get.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":13,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":13,"endColumn":20}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\nimport type { JsonValue } from '@/types/utility-types'\nimport type { TenantContext } from '@/dbal/core/foundation/tenant-context'\n\ninterface StoreContext {\n getKey: (key: string, context: TenantContext) => string\n store: Map\n}\n\nexport function get(this: StoreContext, key: string, context: TenantContext): JsonValue | null {\n const fullKey = this.getKey(key, context)\n const item = this.store.get(fullKey)\n if (item === null || item === undefined) return null\n if (item.expiry !== undefined && Date.now() > item.expiry) {\n this.store.delete(fullKey)\n return null\n }\n return item.value\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/handle-error.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/has-tenant.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":5,"column":3,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":5,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":5,"column":10,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":5,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tenants on an `any` value.","line":5,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":5,"endColumn":22}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":33,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":36,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[179,182],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[179,182],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function hasTenant(this: any, id: string): boolean {\n return this.tenants.has(id)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/initialize.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'initialize' has no 'await' expression.","line":19,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":19,"endColumn":33,"suggestions":[{"messageId":"removeAsync","fix":{"range":[523,594],"text":"function initialize(config?: Partial<_DBALConfig>): void"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable boolean value in conditional. Please handle the nullish case explicitly.","line":20,"column":7,"nodeType":"MemberExpression","messageId":"conditionErrorNullableBoolean","endLine":20,"endColumn":24,"suggestions":[{"messageId":"conditionFixDefaultFalse","fix":{"range":[603,620],"text":"state.initialized ?? false"},"desc":"Explicitly treat nullish value the same as false (`value ?? false`)"},{"messageId":"conditionFixCompareTrue","fix":{"range":[603,620],"text":"state.initialized === true"},"desc":"Change condition to check if true (`value === true`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected value in conditional. A boolean expression is required.","line":38,"column":16,"nodeType":"ChainExpression","messageId":"conditionErrorOther","endLine":38,"endColumn":31},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":38,"column":32,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":38,"endColumn":34,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[1067,1069],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { DBALClient as _DBALClient, type DBALConfig as _DBALConfig } from '@/dbal'\nimport { InMemoryKVStore } from '@/dbal/core/kv'\nimport { MemoryStorage } from '@/dbal/blob/providers/memory-storage'\nimport { setInitialized } from './is-initialized'\n\ninterface DBALIntegrationState {\n initialized?: boolean\n tenantManager?: unknown\n kvStore?: InMemoryKVStore\n blobStorage?: MemoryStorage\n client?: _DBALClient\n}\n\nconst state: DBALIntegrationState = {}\n\n/**\n * Initialize the DBAL client with configuration\n */\nexport async function initialize(config?: Partial<_DBALConfig>): Promise {\n if (state.initialized) {\n console.warn('DBAL already initialized')\n return\n }\n\n try {\n // Initialize tenant manager (stub for now)\n state.tenantManager = { tenants: new Map() }\n \n // Initialize KV store\n state.kvStore = new InMemoryKVStore()\n\n // Initialize blob storage\n state.blobStorage = new MemoryStorage()\n\n // Initialize DBAL client\n const dbalConfig: _DBALConfig = {\n mode: 'development',\n adapter: config?.adapter || 'prisma',\n ...config,\n } as _DBALConfig\n\n state.client = new _DBALClient(dbalConfig)\n\n state.initialized = true\n setInitialized(true)\n } catch (error) {\n console.error('Failed to initialize DBAL:', error)\n throw error\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/is-initialized.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/kv-delete.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":9,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":9,"endColumn":20,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[277,289],"text":"(Boolean(this.kvStore))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .kvStore on an `any` value.","line":9,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":9,"endColumn":20},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":9,"column":25,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":9,"endColumn":43,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[294,312],"text":"(Boolean(this.tenantManager))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tenantManager on an `any` value.","line":9,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":9,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":10,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":10,"endColumn":78},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":10,"column":25,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":10,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tenantManager on an `any` value.","line":10,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":10,"endColumn":43},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":11,"column":8,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":11,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[439,446],"text":"(Boolean(context))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":12,"column":3,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":12,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":12,"column":10,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":12,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .kvStore on an `any` value.","line":12,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":12,"endColumn":22}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":38,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":41,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[184,187],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[184,187],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":11,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function kvDelete(this: any,\n key: string,\n tenantId = 'default',\n userId = 'system'\n): Promise {\n if (!this.kvStore || !this.tenantManager) throw new Error('DBAL not initialized')\n const context = await this.tenantManager.getTenantContext(tenantId, userId)\n if (!context) throw new Error(`Tenant not found: ${tenantId}`)\n return this.kvStore.delete(key, context)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/kv-get.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'kvGet' has no 'await' expression.","line":6,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":6,"endColumn":43,"suggestions":[{"messageId":"removeAsync","fix":{"range":[274,392],"text":"function kvGet(\n key: string,\n _tenantId = 'default',\n _userId = 'system'\n): T | null"},"desc":"Remove 'async'."}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\nimport type { JsonValue } from '@/types/utility-types'\n\n// Note: This was extracted from a class method\n// The original `this` context is lost, so this function may not work correctly\nexport async function kvGet(\n key: string,\n _tenantId = 'default',\n _userId = 'system'\n): Promise {\n // Original code referenced this.kvStore and this.tenantManager which don't exist here\n // TODO: Review and fix this extraction\n throw new Error('kvGet was incorrectly extracted - needs manual review')\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/kv-list-add.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":11,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":11,"endColumn":20,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[352,364],"text":"(Boolean(this.kvStore))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .kvStore on an `any` value.","line":11,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":11,"endColumn":20},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":11,"column":25,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":11,"endColumn":43,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[369,387],"text":"(Boolean(this.tenantManager))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tenantManager on an `any` value.","line":11,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":11,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":12,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":12,"endColumn":78},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":12,"column":25,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":12,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tenantManager on an `any` value.","line":12,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":12,"endColumn":43},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":13,"column":8,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":13,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[514,521],"text":"(Boolean(context))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":14,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":14,"endColumn":29},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .kvStore on an `any` value.","line":14,"column":14,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":14,"endColumn":21}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":5,"column":39,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":5,"endColumn":42,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[240,243],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[240,243],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":10,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\nimport type { JsonValue } from '@/types/utility-types'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function kvListAdd(this: any,\n key: string,\n items: JsonValue[],\n tenantId = 'default',\n userId = 'system'\n): Promise {\n if (!this.kvStore || !this.tenantManager) throw new Error('DBAL not initialized')\n const context = await this.tenantManager.getTenantContext(tenantId, userId)\n if (!context) throw new Error(`Tenant not found: ${tenantId}`)\n await this.kvStore.listAdd(key, items, context)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/kv-list-get.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":12,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":12,"endColumn":20,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[371,383],"text":"(Boolean(this.kvStore))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .kvStore on an `any` value.","line":12,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":12,"endColumn":20},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":12,"column":25,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":12,"endColumn":43,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[388,406],"text":"(Boolean(this.tenantManager))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tenantManager on an `any` value.","line":12,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":12,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":13,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":13,"endColumn":78},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":13,"column":25,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":13,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tenantManager on an `any` value.","line":13,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":13,"endColumn":43},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":14,"column":8,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":14,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[533,540],"text":"(Boolean(context))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-return","severity":1,"message":"Unsafe return of a value of type `any`.","line":15,"column":3,"nodeType":"ReturnStatement","messageId":"unsafeReturn","endLine":15,"endColumn":56},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":15,"column":10,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":15,"endColumn":30},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .kvStore on an `any` value.","line":15,"column":15,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":15,"endColumn":22}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":5,"column":39,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":5,"endColumn":42,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[240,243],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[240,243],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":11,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\nimport type { JsonValue } from '@/types/utility-types'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function kvListGet(this: any,\n key: string,\n tenantId = 'default',\n userId = 'system',\n start?: number,\n end?: number\n): Promise {\n if (!this.kvStore || !this.tenantManager) throw new Error('DBAL not initialized')\n const context = await this.tenantManager.getTenantContext(tenantId, userId)\n if (!context) throw new Error(`Tenant not found: ${tenantId}`)\n return this.kvStore.listGet(key, context, start, end)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/kv-set.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":13,"column":8,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":13,"endColumn":20,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[385,397],"text":"(Boolean(this.kvStore))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .kvStore on an `any` value.","line":13,"column":13,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":13,"endColumn":20},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":13,"column":25,"nodeType":"MemberExpression","messageId":"conditionErrorAny","endLine":13,"endColumn":43,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[402,420],"text":"(Boolean(this.tenantManager))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tenantManager on an `any` value.","line":13,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":13,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":14,"column":9,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":14,"endColumn":78},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":14,"column":25,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":14,"endColumn":60},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tenantManager on an `any` value.","line":14,"column":30,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":14,"endColumn":43},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":15,"column":8,"nodeType":"Identifier","messageId":"conditionErrorAny","endLine":15,"endColumn":15,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[547,554],"text":"(Boolean(context))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":16,"column":9,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":16,"endColumn":25},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .kvStore on an `any` value.","line":16,"column":14,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":16,"endColumn":21}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":6,"column":35,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":6,"endColumn":38,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[259,262],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[259,262],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":10,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\nimport type { JsonValue } from '@/types/utility-types'\n\n// KV Store operations\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function kvSet(this: any,\n key: string,\n value: JsonValue,\n ttl?: number,\n tenantId = 'default',\n userId = 'system'\n): Promise {\n if (!this.kvStore || !this.tenantManager) throw new Error('DBAL not initialized')\n const context = await this.tenantManager.getTenantContext(tenantId, userId)\n if (!context) throw new Error(`Tenant not found: ${tenantId}`)\n await this.kvStore.set(key, value, context, ttl)\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/list-add.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'listAdd' has no 'await' expression.","line":5,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":5,"endColumn":30,"suggestions":[{"messageId":"removeAsync","fix":{"range":[221,434],"text":"function listAdd(\n this: { getKey: (key: string, context: TenantContext) => string; store: Map },\n key: string,\n items: JsonValue[],\n context: TenantContext\n): void"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected value in conditional. A boolean expression is required.","line":12,"column":21,"nodeType":"ChainExpression","messageId":"conditionErrorOther","endLine":12,"endColumn":51},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":12,"column":52,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":12,"endColumn":54,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[532,534],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\nimport type { JsonValue } from '@/types/utility-types'\nimport type { TenantContext } from '@/dbal/core/foundation/tenant-context'\n\nexport async function listAdd(\n this: { getKey: (key: string, context: TenantContext) => string; store: Map },\n key: string,\n items: JsonValue[],\n context: TenantContext\n): Promise {\n const fullKey = this.getKey(key, context)\n const existing = (this.store.get(fullKey)?.value || []) as JsonValue[]\n this.store.set(fullKey, { value: [...existing, ...items] })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/list-get.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'listGet' has no 'await' expression.","line":5,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":5,"endColumn":30,"suggestions":[{"messageId":"removeAsync","fix":{"range":[221,453],"text":"function listGet(\n this: { getKey: (key: string, context: TenantContext) => string; store: Map },\n key: string,\n context: TenantContext,\n start?: number,\n end?: number\n): JsonValue[]"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected value in conditional. A boolean expression is required.","line":13,"column":17,"nodeType":"ChainExpression","messageId":"conditionErrorOther","endLine":13,"endColumn":47},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":13,"column":48,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":13,"endColumn":50,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[547,549],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\nimport type { JsonValue } from '@/types/utility-types'\nimport type { TenantContext } from '@/dbal/core/foundation/tenant-context'\n\nexport async function listGet(\n this: { getKey: (key: string, context: TenantContext) => string; store: Map },\n key: string,\n context: TenantContext,\n start?: number,\n end?: number\n): Promise {\n const fullKey = this.getKey(key, context)\n const list = (this.store.get(fullKey)?.value || []) as JsonValue[]\n if (start !== undefined && end !== undefined) {\n return list.slice(start, end)\n }\n return list\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/list.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'list' has no 'await' expression.","line":4,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":4,"endColumn":27,"suggestions":[{"messageId":"removeAsync","fix":{"range":[154,254],"text":"function list(this: any, options?: { prefix?: string }): { items: { key: string }[] }"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":6,"column":21,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":6,"endColumn":36},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobs on an `any` value.","line":6,"column":26,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":6,"endColumn":31},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":7,"column":10,"nodeType":"ChainExpression","messageId":"conditionErrorNullableString","endLine":7,"endColumn":25,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[344,360],"text":"((options?.prefix) == null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[345,360],"text":"((options?.prefix) ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[344,360],"text":"(!Boolean((options?.prefix)))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected any value in conditional. An explicit comparison or type conversion is required.","line":7,"column":29,"nodeType":"CallExpression","messageId":"conditionErrorAny","endLine":7,"endColumn":59,"suggestions":[{"messageId":"conditionFixCastBoolean","fix":{"range":[364,394],"text":"(Boolean(key.startsWith(options.prefix)))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":7,"column":29,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":7,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .startsWith on an `any` value.","line":7,"column":33,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":7,"endColumn":43},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":8,"column":20,"nodeType":"Property","messageId":"anyAssignment","endLine":8,"endColumn":23}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":34,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":37,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[180,183],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[180,183],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":8,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function list(this: any, options?: { prefix?: string }): Promise<{ items: { key: string }[] }> {\n const items: { key: string }[] = []\n for (const key of this.blobs.keys()) {\n if (!options?.prefix || key.startsWith(options.prefix)) {\n items.push({ key })\n }\n }\n return { items }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/reset.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .client on an `any` value.","line":5,"column":8,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":5,"endColumn":14},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .tenantManager on an `any` value.","line":6,"column":8,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":6,"endColumn":21},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .kvStore on an `any` value.","line":7,"column":8,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":7,"endColumn":15},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobStorage on an `any` value.","line":8,"column":8,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":8,"endColumn":19},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .initialized on an `any` value.","line":9,"column":8,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":9,"endColumn":19}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":29,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":32,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[175,178],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[175,178],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":5,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function reset(this: any): void {\n this.client = null\n this.tenantManager = null\n this.kvStore = null\n this.blobStorage = null\n this.initialized = false\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/set.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'set' has no 'await' expression.","line":10,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":10,"endColumn":26,"suggestions":[{"messageId":"removeAsync","fix":{"range":[367,501],"text":"function set(\n this: StoreContext,\n key: string,\n value: JsonValue,\n context: TenantContext,\n ttl?: number\n): void"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable number value in conditional. Please handle the nullish/zero/NaN cases explicitly.","line":18,"column":18,"nodeType":"Identifier","messageId":"conditionErrorNullableNumber","endLine":18,"endColumn":21,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[565,568],"text":"(ttl != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultZero","fix":{"range":[565,568],"text":"(ttl ?? 0)"},"desc":"Explicitly treat nullish value the same as 0 (`value ?? 0`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[565,568],"text":"(Boolean(ttl))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\nimport type { JsonValue } from '@/types/utility-types'\nimport type { TenantContext } from '@/dbal/core/foundation/tenant-context'\n\ninterface StoreContext {\n getKey: (key: string, context: TenantContext) => string\n store: Map\n}\n\nexport async function set(\n this: StoreContext,\n key: string,\n value: JsonValue,\n context: TenantContext,\n ttl?: number\n): Promise {\n const fullKey = this.getKey(key, context)\n const expiry = ttl ? Date.now() + ttl * 1000 : undefined\n this.store.set(fullKey, { value, expiry })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/upload.ts","messages":[{"ruleId":"@typescript-eslint/require-await","severity":1,"message":"Async function 'upload' has no 'await' expression.","line":4,"column":8,"nodeType":"FunctionDeclaration","messageId":"missingAwait","endLine":4,"endColumn":29,"suggestions":[{"messageId":"removeAsync","fix":{"range":[154,270],"text":"function upload(this: any,\n key: string,\n data: Buffer,\n metadata?: Record\n): void"},"desc":"Remove 'async'."}]},{"ruleId":"@typescript-eslint/no-unsafe-call","severity":1,"message":"Unsafe call of a(n) `any` typed value.","line":9,"column":3,"nodeType":"MemberExpression","messageId":"unsafeCall","endLine":9,"endColumn":17},{"ruleId":"@typescript-eslint/no-unsafe-member-access","severity":1,"message":"Unsafe member access .blobs on an `any` value.","line":9,"column":8,"nodeType":"Identifier","messageId":"unsafeMemberExpression","endLine":9,"endColumn":13},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":9,"column":41,"nodeType":"Identifier","messageId":"conditionErrorNullableObject","endLine":9,"endColumn":49,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[313,321],"text":"(metadata != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":9,"column":50,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":9,"endColumn":52,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[322,324],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]}],"suppressedMessages":[{"ruleId":"@typescript-eslint/no-explicit-any","severity":2,"message":"Unexpected any. Specify a different type.","line":4,"column":36,"nodeType":"TSAnyKeyword","messageId":"unexpectedAny","endLine":4,"endColumn":39,"suggestions":[{"messageId":"suggestUnknown","fix":{"range":[182,185],"text":"unknown"},"desc":"Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct."},{"messageId":"suggestNever","fix":{"range":[182,185],"text":"never"},"desc":"Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of."}],"suppressions":[{"kind":"directive","justification":""}]}],"errorCount":0,"fatalErrorCount":0,"warningCount":5,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { DBALClient as _DBALClient, DBALConfig as _DBALConfig } from '@/dbal'\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport async function upload(this: any,\n key: string,\n data: Buffer,\n metadata?: Record\n): Promise {\n this.blobs.set(key, { data, metadata: metadata || {} })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/core/client/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/dbal/daemon/client.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":1,"column":28,"nodeType":"MemberExpression","messageId":"conditionErrorNullableString","endLine":1,"endColumn":55,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[27,54],"text":"(process.env.DBAL_DAEMON_URL != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[27,54],"text":"(process.env.DBAL_DAEMON_URL ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[27,54],"text":"(Boolean(process.env.DBAL_DAEMON_URL))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":1,"column":56,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":1,"endColumn":58,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[55,57],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":17,"column":7,"nodeType":"MemberExpression","messageId":"conditionErrorNullableString","endLine":17,"endColumn":31,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[549,573],"text":"process.env.DBAL_API_KEY != null"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[549,573],"text":"process.env.DBAL_API_KEY ?? \"\""},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[549,573],"text":"Boolean(process.env.DBAL_API_KEY)"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":35,"column":21,"nodeType":"ChainExpression","messageId":"conditionErrorNullableString","endLine":35,"endColumn":34,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[1010,1023],"text":"((body?.message) != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[1010,1023],"text":"((body?.message) ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[1010,1023],"text":"(Boolean((body?.message)))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":35,"column":25,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":35,"endColumn":27,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1014,1016],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":35,"column":35,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":35,"endColumn":37,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[1024,1026],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":38,"column":11,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":38,"endColumn":13,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1072,1074],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":39,"column":21,"nodeType":"MemberExpression","messageId":"conditionErrorNullableString","endLine":39,"endColumn":33,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[1115,1127],"text":"(body.message != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[1115,1127],"text":"(body.message ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[1115,1127],"text":"(Boolean(body.message))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":39,"column":34,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":39,"endColumn":36,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[1128,1130],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":42,"column":14,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":42,"endColumn":16,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1181,1183],"text":"."},"desc":"Remove unnecessary optional chain"}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":10,"fixableErrorCount":0,"fixableWarningCount":0,"source":"const DEFAULT_DAEMON_URL = process.env.DBAL_DAEMON_URL || 'http://localhost:8080/api/dbal'\n\nexport type DaemonEntity = 'User'\nexport type DaemonAction = 'list' | 'get' | 'read' | 'create' | 'update' | 'delete'\n\nexport interface DaemonRpcRequest {\n entity: DaemonEntity\n action: DaemonAction\n payload?: Record\n options?: Record\n}\n\nexport async function callDaemon(request: DaemonRpcRequest): Promise {\n const headers: Record = {\n 'Content-Type': 'application/json',\n }\n if (process.env.DBAL_API_KEY) {\n headers['x-dbal-api-key'] = process.env.DBAL_API_KEY\n }\n\n const response = await fetch(DEFAULT_DAEMON_URL, {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n })\n\n let body: { success?: boolean; message?: string; data?: T }\n try {\n body = (await response.json()) as typeof body\n } catch {\n throw new Error('Failed to parse response from DBAL daemon')\n }\n\n if (!response.ok) {\n throw new Error(body?.message || 'DBAL daemon request failed')\n }\n\n if (body?.success === false) {\n throw new Error(body.message || 'DBAL daemon reported failure')\n }\n\n return body?.data as T\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/declarative-component-renderer.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/github/create-github-client.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":10,"column":21,"nodeType":"Identifier","messageId":"conditionErrorNullableString","endLine":10,"endColumn":26,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[205,210],"text":"(token != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[205,210],"text":"(token ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[205,210],"text":"(Boolean(token))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":10,"column":27,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":10,"endColumn":29,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[211,213],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":12,"column":8,"nodeType":"Identifier","messageId":"conditionErrorNullableString","endLine":12,"endColumn":17,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[248,258],"text":"authToken == null"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[249,258],"text":"(authToken ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[248,258],"text":"!Boolean(authToken)"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Create GitHub client using Octokit\n */\n\nimport { Octokit } from 'octokit'\n\nexport type GitHubClient = Octokit\n\nexport function createGitHubClient(token?: string): GitHubClient {\n const authToken = token || process.env.GITHUB_TOKEN\n \n if (!authToken) {\n throw new Error('GitHub token is required. Provide a token parameter or set GITHUB_TOKEN environment variable.')\n }\n\n return new Octokit({\n auth: authToken,\n })\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/github/fetch-workflow-run-logs.ts","messages":[{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":52,"column":10,"nodeType":"Identifier","messageId":"conditionErrorNullableString","endLine":52,"endColumn":14,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[1180,1185],"text":"(repo == null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[1181,1185],"text":"(repo ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[1180,1185],"text":"(!Boolean(repo))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable number value in conditional. Please handle the nullish/zero/NaN cases explicitly.","line":52,"column":19,"nodeType":"Identifier","messageId":"conditionErrorNullableNumber","endLine":52,"endColumn":24,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[1189,1195],"text":"(runId == null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultZero","fix":{"range":[1190,1195],"text":"(runId ?? 0)"},"desc":"Explicitly treat nullish value the same as 0 (`value ?? 0`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[1189,1195],"text":"(!Boolean(runId))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":68,"column":8,"nodeType":"Identifier","messageId":"conditionErrorNullableObject","endLine":68,"endColumn":14,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[1609,1616],"text":"client == null"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable number value in conditional. Please handle the nullish/zero/NaN cases explicitly.","line":85,"column":17,"nodeType":"Identifier","messageId":"conditionErrorNullableNumber","endLine":85,"endColumn":25,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[1996,2004],"text":"(jobLimit != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultZero","fix":{"range":[1996,2004],"text":"(jobLimit ?? 0)"},"desc":"Explicitly treat nullish value the same as 0 (`value ?? 0`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[1996,2004],"text":"(Boolean(jobLimit))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":85,"column":26,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":85,"endColumn":28,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[2005,2007],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected value in conditional. A boolean expression is required.","line":94,"column":21,"nodeType":"MemberExpression","messageId":"conditionErrorOther","endLine":94,"endColumn":35},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":94,"column":36,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":94,"endColumn":38,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[2250,2252],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":7,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Fetch workflow run logs\n */\n\nimport type { Octokit } from 'octokit'\n\nexport interface WorkflowJob {\n id: number\n name: string\n status: string\n conclusion?: string\n}\n\nexport interface WorkflowRunLogs {\n logs: string\n runId: number\n jobs?: WorkflowJob[]\n logsText?: string\n truncated?: boolean\n}\n\nexport interface FetchWorkflowRunLogsOptions {\n client?: Octokit\n owner: string\n repo: string\n runId: number\n runName?: string\n includeLogs?: boolean\n jobLimit?: number\n tailLines?: number\n failedOnly?: boolean\n}\n\nexport async function fetchWorkflowRunLogs(\n options: FetchWorkflowRunLogsOptions\n): Promise\nexport async function fetchWorkflowRunLogs(\n owner: string,\n repo: string,\n runId: number,\n options?: { tailLines?: number; failedOnly?: boolean }\n): Promise\nexport async function fetchWorkflowRunLogs(\n ownerOrOptions: string | FetchWorkflowRunLogsOptions,\n repo?: string,\n runId?: number,\n options?: { tailLines?: number; failedOnly?: boolean }\n): Promise {\n // Parse arguments\n let opts: FetchWorkflowRunLogsOptions\n if (typeof ownerOrOptions === 'string') {\n if (!repo || !runId) {\n throw new Error('repo and runId are required when using positional arguments')\n }\n opts = {\n owner: ownerOrOptions,\n repo,\n runId,\n tailLines: options?.tailLines,\n failedOnly: options?.failedOnly,\n }\n } else {\n opts = ownerOrOptions\n }\n\n const { client, owner, repo: repoName, runId: workflowRunId, includeLogs = true, jobLimit, failedOnly = false } = opts\n\n if (!client) {\n // Return stub data when no client is provided\n return {\n logs: '',\n runId: workflowRunId,\n jobs: [],\n logsText: '',\n truncated: false,\n }\n }\n\n try {\n // Fetch workflow jobs\n const { data: jobsData } = await client.rest.actions.listJobsForWorkflowRun({\n owner,\n repo: repoName,\n run_id: workflowRunId,\n per_page: jobLimit || 100,\n })\n\n const jobs = jobsData.jobs\n .filter((job) => !failedOnly || job.conclusion === 'failure')\n .map((job) => ({\n id: job.id,\n name: job.name,\n status: job.status,\n conclusion: job.conclusion || undefined,\n }))\n\n let logsText = ''\n const truncated = false\n\n if (includeLogs) {\n // Download logs for the workflow run\n try {\n const { data: logsData } = await client.rest.actions.downloadWorkflowRunLogs({\n owner,\n repo: repoName,\n run_id: workflowRunId,\n })\n \n // The logs are returned as a zip file URL or buffer\n // For simplicity, we'll just note that logs are available\n logsText = typeof logsData === 'string' ? logsData : '[Binary log data available]'\n } catch (error) {\n console.warn('Failed to download logs:', error)\n logsText = '[Logs not available]'\n }\n }\n\n return {\n logs: logsText,\n runId: workflowRunId,\n jobs,\n logsText,\n truncated,\n }\n } catch (error) {\n console.error('Failed to fetch workflow run logs:', error)\n return null\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/github/parse-workflow-run-logs-options.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/github/resolve-github-repo.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":14,"column":14,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":14,"endColumn":28},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":15,"column":13,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":15,"endColumn":26}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Resolve GitHub repository\n */\n\nexport interface GitHubRepo {\n owner: string\n repo: string\n}\n\nexport function resolveGitHubRepo(params: URLSearchParams | string): GitHubRepo {\n if (typeof params === 'string') {\n const [owner, repo] = params.split('/')\n return { \n owner: owner !== null && owner !== undefined && owner !== '' ? owner : '', \n repo: repo !== null && repo !== undefined && repo !== '' ? repo : '' \n }\n }\n \n const ownerParam = params.get('owner')\n const repoParam = params.get('repo')\n return {\n owner: ownerParam !== null && ownerParam !== '' ? ownerParam : '',\n repo: repoParam !== null && repoParam !== '' ? repoParam : '',\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/github/workflows/listing/list-workflow-runs.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/hooks/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/hooks/use-rest-api.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":43,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":43,"endColumn":28},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":44,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":44,"endColumn":28},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":46,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":46,"endColumn":29},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":52,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":52,"endColumn":31},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":71,"column":18,"nodeType":"ChainExpression","messageId":"conditionErrorNullableString","endLine":71,"endColumn":33,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[1967,1982],"text":"((options?.tenant) != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[1967,1982],"text":"((options?.tenant) ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[1967,1982],"text":"(Boolean((options?.tenant)))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":71,"column":34,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":71,"endColumn":36,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[1983,1985],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":72,"column":28,"nodeType":"ChainExpression","messageId":"conditionErrorNullableString","endLine":72,"endColumn":46,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[2035,2053],"text":"((options?.packageId) != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[2035,2053],"text":"((options?.packageId) ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[2035,2053],"text":"(Boolean((options?.packageId)))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":72,"column":47,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":72,"endColumn":49,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[2054,2056],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":83,"column":12,"nodeType":"Identifier","messageId":"conditionErrorNullableString","endLine":83,"endColumn":18,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[2435,2442],"text":"tenant == null"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[2436,2442],"text":"(tenant ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[2435,2442],"text":"!Boolean(tenant)"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":86,"column":19,"nodeType":"Identifier","messageId":"conditionErrorNullableString","endLine":86,"endColumn":30,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[2518,2529],"text":"(pkgOverride != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[2518,2529],"text":"(pkgOverride ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[2518,2529],"text":"(Boolean(pkgOverride))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":86,"column":31,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":86,"endColumn":33,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[2530,2532],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":87,"column":12,"nodeType":"Identifier","messageId":"conditionErrorNullableString","endLine":87,"endColumn":15,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[2560,2564],"text":"pkg == null"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[2561,2564],"text":"(pkg ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[2560,2564],"text":"!Boolean(pkg)"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":91,"column":11,"nodeType":"Identifier","messageId":"conditionErrorNullableString","endLine":91,"endColumn":13,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[2686,2688],"text":"id != null"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[2686,2688],"text":"id ?? \"\""},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[2686,2688],"text":"Boolean(id)"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":92,"column":11,"nodeType":"Identifier","messageId":"conditionErrorNullableString","endLine":92,"endColumn":17,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[2716,2722],"text":"action != null"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[2716,2722],"text":"action ?? \"\""},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[2716,2722],"text":"Boolean(action)"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":107,"column":58,"nodeType":"Identifier","messageId":"conditionErrorNullableObject","endLine":107,"endColumn":65,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[3049,3056],"text":"(options != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":107,"column":66,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":107,"endColumn":68,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[3057,3059],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":110,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":110,"endColumn":61},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":113,"column":27,"nodeType":"MemberExpression","messageId":"conditionErrorNullableString","endLine":113,"endColumn":37,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[3324,3334],"text":"(json.error != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[3324,3334],"text":"(json.error ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[3324,3334],"text":"(Boolean(json.error))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":113,"column":38,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":113,"endColumn":40,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[3335,3337],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":116,"column":16,"nodeType":"MemberExpression","messageId":"conditionErrorNullableObject","endLine":116,"endColumn":25,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[3382,3391],"text":"(json.data != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":116,"column":26,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":116,"endColumn":28,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[3392,3394],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":139,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":139,"endColumn":59},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":142,"column":27,"nodeType":"MemberExpression","messageId":"conditionErrorNullableString","endLine":142,"endColumn":37,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[4002,4012],"text":"(json.error != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[4002,4012],"text":"(json.error ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[4002,4012],"text":"(Boolean(json.error))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":142,"column":38,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":142,"endColumn":40,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[4013,4015],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected value in conditional. A boolean expression is required.","line":145,"column":16,"nodeType":"MemberExpression","messageId":"conditionErrorOther","endLine":145,"endColumn":25},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":145,"column":26,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":145,"endColumn":28,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[4070,4072],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":172,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":172,"endColumn":59},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":175,"column":27,"nodeType":"MemberExpression","messageId":"conditionErrorNullableString","endLine":175,"endColumn":37,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[4823,4833],"text":"(json.error != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[4823,4833],"text":"(json.error ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[4823,4833],"text":"(Boolean(json.error))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":175,"column":38,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":175,"endColumn":40,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[4834,4836],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/no-non-null-assertion","severity":1,"message":"Forbidden non-null assertion.","line":178,"column":16,"nodeType":"TSNonNullExpression","messageId":"noNonNull","endLine":178,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":205,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":205,"endColumn":59},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":208,"column":27,"nodeType":"MemberExpression","messageId":"conditionErrorNullableString","endLine":208,"endColumn":37,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[5652,5662],"text":"(json.error != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[5652,5662],"text":"(json.error ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[5652,5662],"text":"(Boolean(json.error))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":208,"column":38,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":208,"endColumn":40,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[5663,5665],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/no-non-null-assertion","severity":1,"message":"Forbidden non-null assertion.","line":211,"column":16,"nodeType":"TSNonNullExpression","messageId":"noNonNull","endLine":211,"endColumn":26},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":234,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":234,"endColumn":62},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":237,"column":27,"nodeType":"MemberExpression","messageId":"conditionErrorNullableString","endLine":237,"endColumn":37,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[6343,6353],"text":"(json.error != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[6343,6353],"text":"(json.error ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[6343,6353],"text":"(Boolean(json.error))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":237,"column":38,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":237,"endColumn":40,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[6354,6356],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":268,"column":17,"nodeType":"Identifier","messageId":"conditionErrorNullableObject","endLine":268,"endColumn":21,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[7071,7075],"text":"(data != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]},{"ruleId":"@typescript-eslint/no-unsafe-assignment","severity":1,"message":"Unsafe assignment of an `any` value.","line":270,"column":15,"nodeType":"VariableDeclarator","messageId":"anyAssignment","endLine":270,"endColumn":59},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable string value in conditional. Please handle the nullish/empty cases explicitly.","line":273,"column":27,"nodeType":"MemberExpression","messageId":"conditionErrorNullableString","endLine":273,"endColumn":37,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[7238,7248],"text":"(json.error != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"},{"messageId":"conditionFixDefaultEmptyString","fix":{"range":[7238,7248],"text":"(json.error ?? \"\")"},"desc":"Explicitly treat nullish value the same as an empty string (`value ?? \"\"`)"},{"messageId":"conditionFixCastBoolean","fix":{"range":[7238,7248],"text":"(Boolean(json.error))"},"desc":"Explicitly convert value to a boolean (`Boolean(value)`)"}]},{"ruleId":"@typescript-eslint/prefer-nullish-coalescing","severity":1,"message":"Prefer using nullish coalescing operator (`??`) instead of a logical or (`||`), as it is a safer operator.","line":273,"column":38,"nodeType":"Punctuator","messageId":"preferNullishOverOr","endLine":273,"endColumn":40,"suggestions":[{"messageId":"suggestNullish","data":{"equals":""},"fix":{"range":[7249,7251],"text":"??"},"desc":"Fix to nullish coalescing operator (`??`)."}]},{"ruleId":"@typescript-eslint/no-non-null-assertion","severity":1,"message":"Forbidden non-null assertion.","line":276,"column":16,"nodeType":"TSNonNullExpression","messageId":"noNonNull","endLine":276,"endColumn":26},{"ruleId":"@typescript-eslint/strict-boolean-expressions","severity":1,"message":"Unexpected nullable object value in conditional. An explicit null check is required.","line":335,"column":7,"nodeType":"Identifier","messageId":"conditionErrorNullableObject","endLine":335,"endColumn":20,"suggestions":[{"messageId":"conditionFixCompareNullish","fix":{"range":[8805,8818],"text":"(tenantContext != null)"},"desc":"Change condition to check for null/undefined (`value != null`)"}]}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":43,"fixableErrorCount":0,"fixableWarningCount":0,"source":"'use client'\n\n/**\n * useRestApi Hook\n * \n * React hook for making RESTful API calls using the tenant routing pattern.\n * Works with the /api/v1/{tenant}/{package}/{entity}/... endpoints.\n * \n * Supports accessing data from:\n * - Primary package (default)\n * - Dependency packages (by specifying packageId)\n */\n\nimport { useState, useCallback } from 'react'\nimport { useTenantOptional } from '@/app/[tenant]/[package]/tenant-context'\n\ninterface ApiResponse {\n success: boolean\n data?: T\n error?: string\n}\n\ninterface UseRestApiOptions {\n tenant?: string\n packageId?: string\n}\n\ninterface RequestOptions {\n take?: number\n skip?: number\n where?: Record\n orderBy?: Record\n /** Override the package for this request (useful for dependency packages) */\n packageId?: string\n}\n\n/**\n * Build query string from options\n */\nfunction buildQueryString(options: RequestOptions): string {\n const params = new URLSearchParams()\n\n if (options.take !== null && options.take !== undefined) params.set('take', options.take.toString())\n if (options.skip !== null && options.skip !== undefined) params.set('skip', options.skip.toString())\n\n if (options.where !== null && options.where !== undefined) {\n for (const [key, value] of Object.entries(options.where)) {\n params.set(`where.${key}`, String(value))\n }\n }\n\n if (options.orderBy !== null && options.orderBy !== undefined) {\n for (const [key, value] of Object.entries(options.orderBy)) {\n params.set(`orderBy.${key}`, value)\n }\n }\n\n const query = params.toString()\n return query.length > 0 ? `?${query}` : ''\n}\n\n/**\n * Hook for making REST API calls\n */\nexport function useRestApi(options?: UseRestApiOptions) {\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState(null)\n\n // Try to get tenant from context, fall back to options\n const tenantContext = useTenantOptional()\n const tenant = options?.tenant || tenantContext?.tenant\n const defaultPackageId = options?.packageId || tenantContext?.packageId\n\n /**\n * Build the base URL for API calls\n * @param entity Entity name\n * @param id Optional record ID\n * @param action Optional action name\n * @param pkgOverride Override the package (for dependency package access)\n */\n const buildUrl = useCallback(\n (entity: string, id?: string, action?: string, pkgOverride?: string) => {\n if (!tenant) {\n throw new Error('Tenant is required')\n }\n const pkg = pkgOverride || defaultPackageId\n if (!pkg) {\n throw new Error('Package is required')\n }\n let url = `/api/v1/${tenant}/${pkg}/${entity}`\n if (id) url += `/${id}`\n if (action) url += `/${action}`\n return url\n },\n [tenant, defaultPackageId]\n )\n\n /**\n * List entities\n */\n const list = useCallback(\n async (entity: string, options?: RequestOptions): Promise => {\n setLoading(true)\n setError(null)\n\n try {\n const { packageId: pkgOverride, ...queryOpts } = options || {}\n const url = buildUrl(entity, undefined, undefined, pkgOverride) + buildQueryString(queryOpts)\n const response = await fetch(url)\n const json: ApiResponse = await response.json()\n\n if (!json.success) {\n throw new Error(json.error || 'Request failed')\n }\n\n return json.data || []\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error'\n setError(message)\n throw err\n } finally {\n setLoading(false)\n }\n },\n [buildUrl]\n )\n\n /**\n * Read single entity\n */\n const read = useCallback(\n async (entity: string, id: string): Promise => {\n setLoading(true)\n setError(null)\n\n try {\n const url = buildUrl(entity, id)\n const response = await fetch(url)\n const json: ApiResponse = await response.json()\n\n if (!json.success) {\n throw new Error(json.error || 'Request failed')\n }\n\n return json.data || null\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error'\n setError(message)\n throw err\n } finally {\n setLoading(false)\n }\n },\n [buildUrl]\n )\n\n /**\n * Create entity\n */\n const create = useCallback(\n async (entity: string, data: Record): Promise => {\n setLoading(true)\n setError(null)\n\n try {\n const url = buildUrl(entity)\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n })\n const json: ApiResponse = await response.json()\n\n if (!json.success) {\n throw new Error(json.error || 'Request failed')\n }\n\n return json.data!\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error'\n setError(message)\n throw err\n } finally {\n setLoading(false)\n }\n },\n [buildUrl]\n )\n\n /**\n * Update entity\n */\n const update = useCallback(\n async (entity: string, id: string, data: Record): Promise => {\n setLoading(true)\n setError(null)\n\n try {\n const url = buildUrl(entity, id)\n const response = await fetch(url, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(data),\n })\n const json: ApiResponse = await response.json()\n\n if (!json.success) {\n throw new Error(json.error || 'Request failed')\n }\n\n return json.data!\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error'\n setError(message)\n throw err\n } finally {\n setLoading(false)\n }\n },\n [buildUrl]\n )\n\n /**\n * Delete entity\n */\n const remove = useCallback(\n async (entity: string, id: string): Promise => {\n setLoading(true)\n setError(null)\n\n try {\n const url = buildUrl(entity, id)\n const response = await fetch(url, { method: 'DELETE' })\n const json: ApiResponse = await response.json()\n\n if (!json.success) {\n throw new Error(json.error || 'Request failed')\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error'\n setError(message)\n throw err\n } finally {\n setLoading(false)\n }\n },\n [buildUrl]\n )\n\n /**\n * Custom action on entity\n */\n const action = useCallback(\n async (\n entity: string,\n id: string,\n actionName: string,\n data?: Record\n ): Promise => {\n setLoading(true)\n setError(null)\n\n try {\n const url = buildUrl(entity, id, actionName)\n const response = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: data ? JSON.stringify(data) : undefined,\n })\n const json: ApiResponse = await response.json()\n\n if (!json.success) {\n throw new Error(json.error || 'Request failed')\n }\n\n return json.data!\n } catch (err) {\n const message = err instanceof Error ? err.message : 'Unknown error'\n setError(message)\n throw err\n } finally {\n setLoading(false)\n }\n },\n [buildUrl]\n )\n\n return {\n loading,\n error,\n list,\n read,\n create,\n update,\n remove,\n action,\n buildUrl,\n }\n}\n\n/**\n * Hook for a specific entity type\n */\nexport function useEntity(entity: string, options?: UseRestApiOptions) {\n const api = useRestApi(options)\n\n return {\n loading: api.loading,\n error: api.error,\n list: (opts?: RequestOptions) => api.list(entity, opts),\n read: (id: string) => api.read(entity, id),\n create: (data: Record) => api.create(entity, data),\n update: (id: string, data: Record) => api.update(entity, id, data),\n remove: (id: string) => api.remove(entity, id),\n action: (id: string, actionName: string, data?: Record) =>\n api.action(entity, id, actionName, data),\n }\n}\n\n/**\n * Hook for accessing entities from a dependency package\n * \n * @example\n * // On a forum_forge page, access user_manager entities\n * const { list: listRoles } = useDependencyEntity('user_manager', 'roles')\n * const roles = await listRoles()\n */\nexport function useDependencyEntity(\n packageId: string,\n entity: string\n) {\n const tenantContext = useTenantOptional()\n \n // Verify package is accessible (either primary or a dependency)\n if (tenantContext && !tenantContext.hasPackage(packageId)) {\n console.warn(\n `Package '${packageId}' is not accessible from '${tenantContext.primaryPackage}'. ` +\n `Add it to dependencies in metadata.json.`\n )\n }\n\n const api = useRestApi({ packageId })\n\n return {\n loading: api.loading,\n error: api.error,\n list: (opts?: Omit) => api.list(entity, opts),\n read: (id: string) => api.read(entity, id),\n create: (data: Record) => api.create(entity, data),\n update: (id: string, data: Record) => api.update(entity, id, data),\n remove: (id: string) => api.remove(entity, id),\n action: (id: string, actionName: string, data?: Record) =>\n api.action(entity, id, actionName, data),\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/level-types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/lua/ui/generate-component-tree.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/lua/ui/types/lua-ui-package.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/package-catalog.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/package-export.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/package-lib/package-export.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/package-types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/core/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/core/package-catalog.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/core/package-definitions/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/core/package-definitions/set-a/forum-classic.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/core/package-definitions/set-a/guestbook-retro.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/core/package-definitions/set-a/spotify-clone.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/core/package-definitions/set-a/youtube-clone.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/core/package-definitions/set-b/ecommerce-basic.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/core/package-definitions/set-b/retro-games.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/core/package-types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/json/functions/get-json-package-by-id.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/json/functions/load-all-json-packages.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/json/functions/load-json-package.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":17,"column":22,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":17,"endColumn":41},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":17,"column":45,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":17,"endColumn":69},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":29,"column":23,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":29,"endColumn":43},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":29,"column":47,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":29,"endColumn":72}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":4,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { readFile } from 'fs/promises'\nimport { join } from 'path'\nimport type { JSONComponent, JSONPackage, JSONPackageMetadata, JSONPermission } from '../types'\n\nexport async function loadJSONPackage(packagePath: string): Promise {\n const metadataPath = join(packagePath, 'package.json')\n const metadataContent = await readFile(metadataPath, 'utf-8')\n const metadata = JSON.parse(metadataContent) as JSONPackageMetadata\n\n let components: JSONComponent[] | undefined\n let hasComponents = false\n try {\n const componentsPath = join(packagePath, 'components', 'ui.json')\n const componentsContent = await readFile(componentsPath, 'utf-8')\n const componentsData = JSON.parse(componentsContent) as { components?: JSONComponent[] }\n components = componentsData.components ?? []\n hasComponents = (components !== null && components !== undefined && Array.isArray(components)) ? components.length > 0 : false\n } catch {\n // Components file doesn't exist\n }\n\n let permissions: JSONPermission[] | undefined\n let hasPermissions = false\n try {\n const permissionsPath = join(packagePath, 'permissions', 'roles.json')\n const permissionsContent = await readFile(permissionsPath, 'utf-8')\n const permissionsData = JSON.parse(permissionsContent) as { permissions?: JSONPermission[] }\n permissions = permissionsData.permissions ?? []\n hasPermissions = (permissions !== null && permissions !== undefined && Array.isArray(permissions)) ? permissions.length > 0 : false\n } catch {\n // Permissions file doesn't exist\n }\n\n let hasStyles = false\n try {\n const stylesPath = join(packagePath, 'styles', 'index.json')\n await readFile(stylesPath, 'utf-8')\n hasStyles = true\n } catch {\n // Styles don't exist\n }\n\n return {\n metadata,\n components,\n permissions,\n hasComponents,\n hasPermissions,\n hasStyles,\n }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/json/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/json/load-json-package.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/json/render-json-component.tsx","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":25,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":25,"endColumn":32},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":66,"column":24,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":66,"endColumn":42},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":231,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":231,"endColumn":33},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":256,"column":12,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":256,"endColumn":30},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":257,"column":12,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":257,"endColumn":29},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":261,"column":12,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":261,"endColumn":31},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":262,"column":12,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":262,"endColumn":32}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":7,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * JSON Component Renderer for Next.js\n *\n * Renders JSON component definitions to React elements\n */\n\nimport React from 'react'\nimport type { JSONComponent } from './types'\nimport type { JsonValue } from '@/types/utility-types'\n\nexport interface RenderContext {\n props: Record\n state: Record\n [key: string]: JsonValue\n}\n\n/**\n * Render a JSON component definition to React\n */\nexport function renderJSONComponent(\n component: JSONComponent,\n props: Record = {},\n ComponentRegistry: Record>> = {}\n): React.ReactElement {\n if (component.render === null || component.render === undefined) {\n return (\n
\n Error: Component {component.name} has no render definition\n
\n )\n }\n\n const context: RenderContext = {\n props,\n state: {},\n }\n\n try {\n const template = component.render.template\n if (template === null || template === undefined) {\n return (\n
\n Warning: Component {component.name} has no template\n
\n )\n }\n return renderTemplate(template, context, ComponentRegistry)\n } catch (error) {\n return (\n
\n Error rendering {component.name}:{' '}\n {error instanceof Error ? error.message : String(error)}\n
\n )\n }\n}\n\n/**\n * Render a template node to React\n */\nfunction renderTemplate(\n node: JsonValue,\n context: RenderContext,\n ComponentRegistry: Record>>\n): React.ReactElement {\n if (node === null || node === undefined || typeof node !== 'object') {\n return <>{String(node)}\n }\n\n // Array case - should not happen at this level but handle gracefully\n if (Array.isArray(node)) {\n return <>{node.map(String).join(', ')}\n }\n\n // Now TypeScript knows it's a JsonObject (non-array object)\n const nodeObj = node as Record\n\n // Handle conditional rendering\n if (nodeObj.type === 'conditional') {\n const conditionValue = nodeObj.condition\n if (conditionValue === null || conditionValue === undefined) {\n return <>\n }\n const condition = evaluateExpression(conditionValue, context)\n const conditionIsTrue = condition !== null && condition !== undefined && condition !== false && condition !== 0 && condition !== ''\n if (conditionIsTrue && nodeObj.then !== null && nodeObj.then !== undefined) {\n return renderTemplate(nodeObj.then, context, ComponentRegistry)\n } else if (!conditionIsTrue && nodeObj.else !== null && nodeObj.else !== undefined) {\n return renderTemplate(nodeObj.else, context, ComponentRegistry)\n }\n return <>\n }\n\n // Handle component references from registry\n const nodeType = nodeObj.type\n if (typeof nodeType === 'string' && (nodeType === 'component' || (ComponentRegistry[nodeType] !== undefined))) {\n const Component = ComponentRegistry[nodeType]\n if (Component !== undefined) {\n const componentProps: Record = {}\n\n // Process props\n const props = nodeObj.props\n if (props !== null && props !== undefined && typeof props === 'object' && !Array.isArray(props)) {\n for (const [key, value] of Object.entries(props)) {\n const evaluated = evaluateExpression(value, context)\n if (evaluated !== undefined) {\n componentProps[key] = evaluated\n }\n }\n }\n\n // Process children\n let children: React.ReactNode = null\n const nodeChildren = nodeObj.children\n if (nodeChildren !== null && nodeChildren !== undefined) {\n if (typeof nodeChildren === 'string') {\n children = evaluateExpression(nodeChildren, context) as React.ReactNode\n } else if (Array.isArray(nodeChildren)) {\n children = nodeChildren.map((child: JsonValue, index: number) => {\n if (typeof child === 'string') {\n return evaluateExpression(child, context) as React.ReactNode\n }\n return (\n \n {renderTemplate(child, context, ComponentRegistry)}\n \n )\n })\n } else {\n children = renderTemplate(nodeChildren, context, ComponentRegistry)\n }\n }\n\n return )}>{children}\n }\n }\n\n // Map JSON element types to HTML elements\n const ElementType = getElementType(typeof nodeType === 'string' ? nodeType : 'div')\n\n // Build props\n const elementProps: Record = {}\n\n if (nodeObj.className !== null && nodeObj.className !== undefined) {\n elementProps.className = nodeObj.className\n }\n\n if (nodeObj.style !== null && nodeObj.style !== undefined) {\n elementProps.style = nodeObj.style\n }\n\n if (nodeObj.href !== null && nodeObj.href !== undefined) {\n const href = evaluateExpression(nodeObj.href, context)\n if (href !== undefined) {\n elementProps.href = href\n }\n }\n\n if (nodeObj.src !== null && nodeObj.src !== undefined) {\n const src = evaluateExpression(nodeObj.src, context)\n if (src !== undefined) {\n elementProps.src = src\n }\n }\n\n if (nodeObj.alt !== null && nodeObj.alt !== undefined) {\n const alt = evaluateExpression(nodeObj.alt, context)\n if (alt !== undefined) {\n elementProps.alt = alt\n }\n }\n\n // Render children\n let children: React.ReactNode = null\n const nodeChildren = nodeObj.children\n if (nodeChildren !== null && nodeChildren !== undefined) {\n if (typeof nodeChildren === 'string') {\n children = evaluateExpression(nodeChildren, context) as React.ReactNode\n } else if (Array.isArray(nodeChildren)) {\n children = nodeChildren.map((child: JsonValue, index: number) => {\n if (typeof child === 'string') {\n return evaluateExpression(child, context) as React.ReactNode\n }\n return (\n \n {renderTemplate(child, context, ComponentRegistry)}\n \n )\n })\n } else {\n children = renderTemplate(nodeChildren, context, ComponentRegistry)\n }\n }\n\n return React.createElement(ElementType, elementProps, children)\n}\n\n/**\n * Map JSON component types to HTML element types\n */\nfunction getElementType(type: string): string {\n const typeMap: Record = {\n Box: 'div',\n Stack: 'div',\n Text: 'span',\n Button: 'button',\n Link: 'a',\n List: 'ul',\n ListItem: 'li',\n Icon: 'span',\n Avatar: 'div',\n Badge: 'div',\n Divider: 'hr',\n Breadcrumbs: 'nav',\n }\n\n return typeMap[type] ?? type\n}\n\n/**\n * Evaluate template expressions like {{variable}}\n */\nfunction evaluateExpression(expr: JsonValue, context: RenderContext): JsonValue | undefined {\n if (typeof expr !== 'string') {\n return expr\n }\n\n // Check if it's a template expression\n const templateMatch = expr.match(/^\\{\\{(.+)\\}\\}$/)\n const matchedExpression = templateMatch?.[1]\n if (matchedExpression !== null && matchedExpression !== undefined && matchedExpression.length > 0) {\n const expression = matchedExpression.trim()\n try {\n return evaluateSimpleExpression(expression, context)\n } catch (error) {\n console.warn(`Failed to evaluate expression: ${expression}`, error)\n return expr\n }\n }\n\n return expr\n}\n\n/**\n * Evaluate simple expressions (no arbitrary code execution)\n */\nfunction evaluateSimpleExpression(expr: string, context: RenderContext): JsonValue | undefined {\n // Handle property access like \"props.title\"\n const parts = expr.split('.')\n let value: JsonValue | undefined = context\n\n for (const part of parts) {\n // Handle ternary operator\n if (part.includes('?')) {\n const [condition, branches] = part.split('?')\n if ((condition === null || condition === undefined || condition.length === 0) || \n (branches === null || branches === undefined || branches.length === 0)) {\n return value\n }\n const [trueBranch, falseBranch] = branches.split(':')\n if ((trueBranch === null || trueBranch === undefined || trueBranch.length === 0) || \n (falseBranch === null || falseBranch === undefined || falseBranch.length === 0)) {\n return value\n }\n const conditionValue = evaluateSimpleExpression(condition.trim(), context)\n const isTrue = conditionValue !== null && conditionValue !== undefined && conditionValue !== false && conditionValue !== 0 && conditionValue !== ''\n return isTrue\n ? evaluateSimpleExpression(trueBranch.trim(), context)\n : evaluateSimpleExpression(falseBranch.trim(), context)\n }\n\n // Handle negation\n if (part.startsWith('!')) {\n const innerPart = part.substring(1)\n if (value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value)) {\n value = (value as Record)[innerPart]\n }\n return value === null || value === undefined || value === false || value === 0 || value === '' ? true : false\n }\n\n // Handle array access or simple property\n if (value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value)) {\n value = (value as Record)[part]\n } else {\n return undefined\n }\n }\n\n return value\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/json/types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/config/default-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/config/development-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/config/get-package-repo-config.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":7,"column":15,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":7,"endColumn":49}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { PackageRepoConfig } from './types'\nimport { DEFAULT_PACKAGE_REPO_CONFIG } from './default-config'\nimport { DEVELOPMENT_PACKAGE_REPO_CONFIG } from './development-config'\nimport { PRODUCTION_PACKAGE_REPO_CONFIG } from './production-config'\n\nexport function getPackageRepoConfig(): PackageRepoConfig {\n const env = process.env.NODE_ENV !== undefined && process.env.NODE_ENV.length > 0 ? process.env.NODE_ENV : 'development'\n const enableRemote = process.env.NEXT_PUBLIC_ENABLE_REMOTE_PACKAGES === 'true'\n\n let config: PackageRepoConfig\n\n switch (env) {\n case 'production':\n config = { ...PRODUCTION_PACKAGE_REPO_CONFIG }\n break\n case 'development':\n case 'test':\n config = { ...DEVELOPMENT_PACKAGE_REPO_CONFIG }\n break\n default:\n config = { ...DEFAULT_PACKAGE_REPO_CONFIG }\n }\n\n if (enableRemote) {\n config.sources = config.sources.map((source) => ({\n ...source,\n enabled: source.type === 'remote' ? true : source.enabled,\n }))\n }\n\n const authToken = process.env.PACKAGE_REGISTRY_AUTH_TOKEN\n if (authToken !== undefined && authToken.length > 0) {\n config.sources = config.sources.map((source) => ({\n ...source,\n authToken: source.type === 'remote' ? authToken : undefined,\n }))\n }\n\n return config\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/config/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/config/production-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/config/types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/config/validate-package-repo-config.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/functions/check-dependencies.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":13,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":13,"endColumn":19},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":14,"column":20,"nodeType":"MemberExpression","messageId":"neverNullish","endLine":14,"endColumn":36},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":14,"column":60,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":14,"endColumn":82}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { PackageRegistry } from '../types'\n\nexport interface DependencyCheckResult {\n satisfied: boolean\n missing: string[]\n}\n\nexport function checkDependencies(\n registry: PackageRegistry,\n packageId: string\n): DependencyCheckResult {\n const pkg = registry[packageId]\n if (pkg === null || pkg === undefined) return { satisfied: false, missing: [packageId] }\n const missing = (pkg.dependencies ?? []).filter((dep) => registry[dep] === null || registry[dep] === undefined)\n return { satisfied: missing.length === 0, missing }\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/functions/get-package-components.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined.","line":4,"column":10,"nodeType":"MemberExpression","messageId":"neverNullish","endLine":4,"endColumn":24}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import type { PackageDefinition } from '../types'\n\nexport function getPackageComponents(pkg: PackageDefinition) {\n return pkg.components ?? []\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/functions/get-package-scripts.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/functions/get-package.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/functions/get-packages-by-category.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/functions/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/package-glue/types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/unified/get-package-metadata.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/unified/get-packages-dir.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/unified/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/unified/list-package-ids.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/unified/load-all-packages.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/unified/load-package.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":27,"column":7,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":27,"endColumn":27}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { join } from 'path'\nimport { PACKAGE_CATALOG } from '../core/package-catalog'\nimport { loadJSONPackage } from '../json'\nimport { getPackagesDir } from './get-packages-dir'\nimport type { UnifiedPackage } from './types'\n\nexport async function loadPackage(packageId: string): Promise {\n try {\n const packagePath = join(getPackagesDir(), packageId)\n const jsonPkg = await loadJSONPackage(packagePath)\n\n return {\n packageId: jsonPkg.metadata.packageId,\n name: jsonPkg.metadata.name,\n version: jsonPkg.metadata.version,\n description: jsonPkg.metadata.description,\n category: jsonPkg.metadata.category,\n minLevel: jsonPkg.metadata.minLevel,\n source: 'json',\n jsonData: jsonPkg,\n }\n } catch {\n // JSON package not found, try legacy catalog\n }\n\n const legacyEntry = PACKAGE_CATALOG[packageId]\n if (legacyEntry !== null && legacyEntry !== undefined) {\n const data = legacyEntry()\n return {\n packageId: data.manifest.id,\n name: data.manifest.name,\n version: data.manifest.version,\n description: data.manifest.description,\n category: data.manifest.category,\n minLevel: 1,\n source: 'legacy',\n legacyData: data,\n }\n }\n\n return null\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/unified/package-exists.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/packages/unified/types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/prisma.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/rendering/declarative-component-renderer.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":22,"column":34,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":22,"endColumn":62},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":25,"column":23,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":25,"endColumn":25,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[993,995],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":30,"column":8,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":30,"endColumn":10,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1209,1211],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":31,"column":8,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":31,"endColumn":10,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1234,1236],"text":""},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary optional chain on a non-nullish value.","line":37,"column":45,"nodeType":"MemberExpression","messageId":"neverOptionalChain","endLine":37,"endColumn":47,"suggestions":[{"messageId":"suggestRemoveOptionalChain","fix":{"range":[1508,1510],"text":"."},"desc":"Remove unnecessary optional chain"}]},{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":44,"column":23,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":44,"endColumn":38}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":6,"fixableErrorCount":0,"fixableWarningCount":0,"source":"/**\n * Minimal declarative component registry\n *\n * Provides a tiny in-memory registry and a helper to load package component\n * definitions (used by the package initialization flow). This is intentionally\n * small — it avoids pulling in the full renderer while allowing packages to\n * register their component metadata at startup.\n */\n\nimport type { JsonValue, JsonObject } from '@/types/utility-types'\n\ntype ComponentDef = JsonObject\n\nconst PACKAGE_COMPONENT_REGISTRY: Record> = {}\n\n/**\n * Load components from a package seed/content object into the registry.\n * The `packageContent` object is expected to include `metadata.packageId`\n * and a `components` array (or object) with component definitions.\n */\nexport function loadPackageComponents(packageContent: JsonValue): void {\n if (packageContent === null || packageContent === undefined || typeof packageContent !== 'object') return\n\n const pkg = packageContent as JsonObject\n const metadata = pkg?.metadata\n const packageId =\n (metadata !== null && metadata !== undefined && typeof metadata === 'object' && !Array.isArray(metadata)\n ? (metadata as JsonObject)['packageId']\n : undefined) ?? \n pkg?.['package'] ?? \n pkg?.['packageId']\n if (packageId === null || packageId === undefined || typeof packageId !== 'string') return\n\n const compsArray: JsonValue[] =\n Array.isArray(pkg.components) && pkg.components.length > 0\n ? pkg.components\n : Array.isArray((pkg.ui as JsonObject)?.components)\n ? ((pkg.ui as JsonObject).components as JsonValue[])\n : []\n\n const compMap: Record = {}\n\n for (const c of compsArray) {\n if (c === null || c === undefined || typeof c !== 'object' || Array.isArray(c)) continue\n const comp = c as JsonObject\n if (comp.id === null || comp.id === undefined || typeof comp.id !== 'string') continue\n compMap[comp.id] = comp\n }\n\n PACKAGE_COMPONENT_REGISTRY[packageId] = {\n ...(PACKAGE_COMPONENT_REGISTRY[packageId] ?? {}),\n ...compMap,\n }\n}\n\nexport function getRegisteredComponent(packageId: string, componentId: string): ComponentDef | null {\n return PACKAGE_COMPONENT_REGISTRY[packageId]?.[componentId] ?? null\n}\n\nexport function listRegisteredPackages(): string[] {\n return Object.keys(PACKAGE_COMPONENT_REGISTRY)\n}\n\nexport function clearRegistry(): void {\n Object.keys(PACKAGE_COMPONENT_REGISTRY).forEach(k => delete PACKAGE_COMPONENT_REGISTRY[k])\n}\n\nexport type { ComponentDef }\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/routing/auth/validate-package-route.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/routing/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/routing/route-parser.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/schema-types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/schema-utils.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/schema/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/schema/schema-registry.ts","messages":[{"ruleId":"@typescript-eslint/prefer-readonly","severity":1,"message":"Member 'schemas' is never reassigned; mark it as `readonly`.","line":10,"column":3,"nodeType":null,"messageId":"preferReadonly","endLine":10,"endColumn":18,"fix":{"range":[245,245],"text":"readonly "}},{"ruleId":"@typescript-eslint/no-confusing-void-expression","severity":1,"message":"Returning a void expression from an arrow function shorthand is forbidden. Please add braces to the arrow function.","line":43,"column":50,"nodeType":"CallExpression","messageId":"invalidVoidExprArrow","endLine":43,"endColumn":81,"fix":{"range":[1222,1253],"text":"{ schemaRegistry.register(schema); }"}}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":2,"source":"/**\n * Schema registry for dynamic schema management\n */\n\nimport type { ModelSchema } from '../types/schema-types'\nimport { readFileSync, writeFileSync, existsSync } from 'fs'\nimport { join } from 'path'\n\nexport class SchemaRegistry {\n private schemas: Map = new Map()\n packages: Record = {}\n\n register(schema: ModelSchema): void {\n this.schemas.set(schema.name, schema)\n }\n\n get(name: string): ModelSchema | undefined {\n return this.schemas.get(name)\n }\n\n getAll(): ModelSchema[] {\n return Array.from(this.schemas.values())\n }\n}\n\nexport const schemaRegistry = new SchemaRegistry()\n\nexport function loadSchemaRegistry(path?: string): SchemaRegistry {\n const schemaPath = path ?? join(process.cwd(), 'schemas', 'registry.json')\n \n if (!existsSync(schemaPath)) {\n return schemaRegistry\n }\n\n try {\n const data = readFileSync(schemaPath, 'utf-8')\n const parsed: unknown = JSON.parse(data)\n \n if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {\n const { schemas, packages } = parsed as { schemas?: unknown; packages?: unknown }\n \n if (Array.isArray(schemas)) {\n schemas.forEach((schema: ModelSchema) => schemaRegistry.register(schema))\n }\n \n if (packages !== null && packages !== undefined && typeof packages === 'object') {\n schemaRegistry.packages = packages as Record\n }\n }\n } catch (error) {\n console.warn(`Failed to load schema registry from ${schemaPath}:`, error instanceof Error ? error.message : String(error))\n }\n\n return schemaRegistry\n}\n\nexport function saveSchemaRegistry(registry: SchemaRegistry, path?: string): void {\n const schemaPath = path ?? join(process.cwd(), 'schemas', 'registry.json')\n \n try {\n const data = {\n schemas: registry.getAll(),\n packages: registry.packages,\n }\n writeFileSync(schemaPath, JSON.stringify(data, null, 2))\n } catch (error) {\n console.error(`Failed to save schema registry to ${schemaPath}:`, error instanceof Error ? error.message : String(error))\n }\n}\n\nexport interface PendingMigration {\n id: string\n packageId: string\n status: string\n queuedAt: string\n entities: Array<{ name: string }>\n}\n\nexport function getPendingMigrations(_registry: SchemaRegistry): PendingMigration[] {\n // TODO: Implement pending migrations retrieval from database\n return []\n}\n\nexport function generatePrismaFragment(registry: SchemaRegistry, _path?: string): string {\n // Generate Prisma schema fragments from registered schemas\n const schemas = registry.getAll()\n const fragments: string[] = []\n\n for (const schema of schemas) {\n fragments.push(`// Model: ${schema.name}`)\n fragments.push(`model ${schema.name} {`)\n \n // Add fields - this is a simplified version\n // Real implementation would need proper field mapping\n fragments.push(' id String @id @default(cuid())')\n fragments.push(' createdAt DateTime @default(now())')\n fragments.push(' updatedAt DateTime @updatedAt')\n \n fragments.push('}')\n fragments.push('')\n }\n\n return fragments.join('\\n')\n}\n\nexport function approveMigration(_migrationId: string, _registry: SchemaRegistry): boolean {\n // TODO: Implement migration approval - update database status\n return false\n}\n\nexport function rejectMigration(_migrationId: string, _registry: SchemaRegistry): boolean {\n // TODO: Implement migration rejection - update database status\n return false\n}\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/seed-data.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/seed/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/types/level-types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/types/schema-types.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/ui-pages/load-page-from-db.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/ui-pages/load-page-from-lua-packages.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/utils.test.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/lib/utils.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/middleware.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/tests/package-integration.test.ts","messages":[{"ruleId":"@typescript-eslint/no-unnecessary-condition","severity":1,"message":"Unnecessary conditional, the types have no overlap.","line":73,"column":11,"nodeType":"BinaryExpression","messageId":"noOverlapBooleanExpression","endLine":73,"endColumn":23}],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import { describe, expect, it } from 'vitest'\n\nimport adminDialogMetadata from '../../../../packages/admin_dialog/seed/metadata.json'\nimport dashboardMetadata from '../../../../packages/dashboard/seed/metadata.json'\nimport dataTableMetadata from '../../../../packages/data_table/seed/metadata.json'\nimport formBuilderMetadata from '../../../../packages/form_builder/seed/metadata.json'\nimport navMenuMetadata from '../../../../packages/nav_menu/seed/metadata.json'\nimport notificationCenterMetadata from '../../../../packages/notification_center/seed/metadata.json'\nimport uiDialogsMetadata from '../../../../packages/ui_dialogs/seed/metadata.json'\nimport uiPermissionsMetadata from '../../../../packages/ui_permissions/seed/metadata.json'\n\nconst packages = [\n adminDialogMetadata,\n dashboardMetadata,\n dataTableMetadata,\n formBuilderMetadata,\n navMenuMetadata,\n notificationCenterMetadata,\n uiDialogsMetadata,\n uiPermissionsMetadata,\n]\n\ndescribe('Package System Integration', () => {\n it('should have all packages with unique IDs', () => {\n const packageIds = packages.map(pkg => pkg.packageId)\n const uniqueIds = new Set(packageIds)\n expect(uniqueIds.size).toBe(packageIds.length)\n })\n\n it('should have all packages with valid versions', () => {\n packages.forEach(pkg => {\n expect(pkg.version).toMatch(/^\\d+\\.\\d+\\.\\d+$/)\n })\n })\n\n it('should have all packages with metadata', () => {\n packages.forEach(pkg => {\n expect(pkg.packageId).toBeDefined()\n expect(pkg.name).toBeDefined()\n expect(pkg.description).toBeDefined()\n expect(pkg.author).toBeDefined()\n })\n })\n\n it('should have all packages with valid categories', () => {\n const validCategories = ['ui', 'data', 'utility', 'system', 'integration']\n packages.forEach(pkg => {\n expect(validCategories).toContain(pkg.category)\n })\n })\n\n it('should have all packages with exports configuration', () => {\n packages.forEach(pkg => {\n expect(pkg.exports).toBeDefined()\n expect(pkg.exports.components).toBeInstanceOf(Array)\n })\n })\n\n it('should have all packages with dependencies array', () => {\n packages.forEach(pkg => {\n expect(pkg.dependencies).toBeInstanceOf(Array)\n })\n })\n\n it('should not have circular dependencies', () => {\n const getDependencies = (pkgId: string, visited = new Set()): Set => {\n if (visited.has(pkgId)) {\n throw new Error(`Circular dependency detected: ${pkgId}`)\n }\n visited.add(pkgId)\n\n const pkg = packages.find(p => p.packageId === pkgId)\n if (pkg === null || pkg === undefined) return visited\n\n pkg.dependencies.forEach((depId: string) => {\n getDependencies(depId, new Set(visited))\n })\n\n return visited\n }\n\n packages.forEach(pkg => {\n expect(() => getDependencies(pkg.packageId)).not.toThrow()\n })\n })\n\n it('should have all dependencies reference valid packages', () => {\n const allPackageIds = packages.map(pkg => pkg.packageId)\n\n packages.forEach(pkg => {\n pkg.dependencies.forEach((depId: string) => {\n expect(allPackageIds).toContain(depId)\n })\n })\n })\n})\n","usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/base/colors.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/base/fonts.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/base/layout.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/base/tokens.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/base/typography.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/colors.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/components.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/dark-theme.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/fonts.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/index.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/layout.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/light-theme.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/modes/components.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/modes/dark-theme.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/modes/light-theme.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/mui-theme.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/types/components.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/types/layout.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/types/palette.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/types/theme.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/theme/typography.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/types/dbal.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/types/dbal/blob.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/types/dbal/core-config.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/types/dbal/core-types.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/types/dbal/kv-store.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/types/dbal/tenant-aware-blob.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/types/dbal/tenant-context.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/types/module-overrides.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/types/monaco-editor-react.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/src/types/utility-types.d.ts","messages":[],"suppressedMessages":[],"errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":[]},{"filePath":"/home/rewrich/Documents/GitHub/metabuilder/frontends/nextjs/vitest.config.ts","messages":[{"ruleId":"@typescript-eslint/no-unsafe-call","severity":2,"message":"Unsafe call of a(n) `error` type typed value.","line":6,"column":13,"nodeType":"Identifier","messageId":"unsafeCall","endLine":6,"endColumn":18}],"suppressedMessages":[],"errorCount":1,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":"import react from '@vitejs/plugin-react-swc'\nimport { resolve } from 'path'\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n plugins: [react()],\n test: {\n environment: 'jsdom',\n globals: true,\n include: ['src/**/*.test.{ts,tsx}'],\n coverage: {\n provider: 'v8',\n reporter: ['text', 'json', 'html'],\n },\n deps: {\n // Use inline to avoid duplicate React instances in tests\n optimizer: {\n web: {\n include: ['@/fakemui', 'react', 'react-dom']\n }\n }\n }\n },\n resolve: {\n dedupe: ['react', 'react-dom'],\n alias: [\n // fakemui aliases must be first (more specific matches first)\n { find: /^@\\/fakemui\\/(.+)$/, replacement: resolve(__dirname, '../../fakemui/$1') },\n { find: /^@\\/fakemui$/, replacement: resolve(__dirname, '../../fakemui/index.ts') },\n // dbal aliases\n { find: /^@\\/dbal\\/(.+)$/, replacement: resolve(__dirname, '../../dbal/development/src/$1') },\n { find: /^@\\/dbal$/, replacement: resolve(__dirname, '../../dbal/development/src') },\n { find: /^@dbal-ui\\/(.+)$/, replacement: resolve(__dirname, '../../dbal/shared/ui/$1') },\n { find: /^@dbal-ui$/, replacement: resolve(__dirname, '../../dbal/shared/ui') },\n // General @ alias last (least specific)\n { find: /^@\\/(.+)$/, replacement: resolve(__dirname, './src/$1') },\n ],\n },\n})\n","usedDeprecatedRules":[]}] diff --git a/packages/code_editor/components/ui.json b/packages/code_editor/components/ui.json index e87a28a50..2205af3b1 100644 --- a/packages/code_editor/components/ui.json +++ b/packages/code_editor/components/ui.json @@ -2,7 +2,7 @@ "$schema": "https://metabuilder.dev/schemas/json-script-components.schema.json", "schemaVersion": "2.0.0", "package": "code_editor", - "description": "Code editor components for JSON, Lua, and theme editing", + "description": "Code editor components for JSON, scripting, and theme editing", "components": [ { "id": "code_editor", @@ -149,15 +149,15 @@ }, { "id": "lua_editor", - "name": "LuaEditor", - "description": "Lua code editor with sandbox execution support", + "name": "ScriptEditor", + "description": "Script editor component with sandbox execution support", "props": [ { "name": "value", "type": "string", "required": false, "default": "", - "description": "Lua code content" + "description": "Script code content" }, { "name": "readOnly", @@ -294,6 +294,6 @@ } ], "exports": { - "components": ["CodeEditor", "JsonEditor", "LuaEditor", "ThemeEditor"] + "components": ["CodeEditor", "JsonEditor", "ScriptEditor", "ThemeEditor"] } } diff --git a/packages/code_editor/package.json b/packages/code_editor/package.json index 9d6998d62..e30f8f207 100644 --- a/packages/code_editor/package.json +++ b/packages/code_editor/package.json @@ -3,7 +3,7 @@ "packageId": "code_editor", "name": "Code Editor", "version": "1.0.0", - "description": "Code editor components for JSON, Lua, and theme editing", + "description": "Code editor components for JSON, scripting, and theme editing", "author": "MetaBuilder", "license": "MIT", "category": "editors", @@ -18,7 +18,7 @@ "components": [ "CodeEditor", "JsonEditor", - "LuaEditor", + "ScriptEditor", "ThemeEditor" ], "scripts": [ diff --git a/packages/code_editor/permissions/roles.json b/packages/code_editor/permissions/roles.json index 01759c904..c853249b0 100644 --- a/packages/code_editor/permissions/roles.json +++ b/packages/code_editor/permissions/roles.json @@ -32,9 +32,9 @@ "minLevel": 5 }, { - "id": "editor.lua.execute", - "name": "Execute Lua Code", - "description": "Execute Lua code in sandbox environment", + "id": "editor.script.execute", + "name": "Execute Scripts", + "description": "Execute scripts in sandbox environment", "resource": "code_editor", "action": "execute", "scope": "global", diff --git a/packages/code_editor/scripts/functions.json b/packages/code_editor/scripts/functions.json index 8d70029cf..ca3b41ee6 100644 --- a/packages/code_editor/scripts/functions.json +++ b/packages/code_editor/scripts/functions.json @@ -2,7 +2,7 @@ "$schema": "https://metabuilder.dev/schemas/json-script.schema.json", "schemaVersion": "2.2.0", "package": "code_editor", - "description": "Code editor functions for JSON, Lua, and theme editing", + "description": "Code editor functions for JSON, scripting, and theme editing", "functions": [ { "id": "json_render", @@ -26,25 +26,25 @@ "category": "json" }, { - "id": "lua_render", - "name": "renderLuaEditor", + "id": "script_render", + "name": "renderScriptEditor", "exported": true, - "description": "Render Lua code editor component", - "category": "lua" + "description": "Render script editor component", + "category": "script" }, { - "id": "lua_validate", - "name": "validateLua", + "id": "script_validate", + "name": "validateScript", "exported": true, - "description": "Validate Lua code syntax", - "category": "lua" + "description": "Validate script syntax", + "category": "script" }, { - "id": "lua_run_sandbox", - "name": "runLuaSandbox", + "id": "script_run_sandbox", + "name": "runScriptSandbox", "exported": true, - "description": "Execute Lua code in sandbox environment", - "category": "lua" + "description": "Execute scripts in sandbox environment", + "category": "script" }, { "id": "theme_render", @@ -73,9 +73,9 @@ "renderJsonEditor", "validateJson", "formatJson", - "renderLuaEditor", - "validateLua", - "runLuaSandbox", + "renderScriptEditor", + "validateScript", + "runScriptSandbox", "renderThemeEditor", "renderColorPicker", "renderModeToggle" diff --git a/packages/code_editor/storybook/stories.json b/packages/code_editor/storybook/stories.json index cd26d0d34..682547c7e 100644 --- a/packages/code_editor/storybook/stories.json +++ b/packages/code_editor/storybook/stories.json @@ -2,7 +2,7 @@ "$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json", "featured": false, "title": "Code Editor Components", - "description": "Code editor components for JSON, Lua, and theme editing", + "description": "Code editor components for JSON, scripting, and theme editing", "stories": [ { "name": "JsonEditor", @@ -15,11 +15,11 @@ } }, { - "name": "LuaEditor", - "render": "lua", - "description": "Lua code editor with sandbox execution", + "name": "ScriptEditor", + "render": "script", + "description": "Script editor with sandbox execution", "args": { - "value": "-- Example Lua script\nlocal function greet(name)\n return \"Hello, \" .. name\nend\n\nreturn greet(\"World\")", + "value": "// Example script\nfunction greet(name) {\n return \"Hello, \" + name;\n}\n\ngreet(\"World\");", "readOnly": false, "showSnippets": true, "showOutput": true @@ -50,8 +50,8 @@ "description": "JSON editor with validation and formatting", "featured": true }, - "lua": { - "description": "Lua code editor with sandbox execution" + "script": { + "description": "Script editor with sandbox execution" }, "theme": { "description": "Theme customization interface" @@ -92,7 +92,7 @@ } ], "scripts": { - "renderFunctions": ["json", "lua", "theme"], + "renderFunctions": ["json", "script", "theme"], "ignoredScripts": ["tests"] }, "parameters": { diff --git a/packages/codegen_studio/components/ui.json b/packages/codegen_studio/components/ui.json index 8d654dd9f..33b6ffda2 100644 --- a/packages/codegen_studio/components/ui.json +++ b/packages/codegen_studio/components/ui.json @@ -374,7 +374,7 @@ "variant": "body2", "component": "pre", "sx": { "whiteSpace": "pre-wrap" }, - "children": "• Scaffold Next.js app shell\n• Add package metadata + Lua hooks\n• Produce CLI bundle + desktop notes\n• Export a ready-to-ship zip" + "children": "• Scaffold Next.js app shell\n• Add package metadata + automation hooks\n• Produce CLI bundle + desktop notes\n• Export a ready-to-ship zip" } ] } diff --git a/packages/css_designer/components/ui.json b/packages/css_designer/components/ui.json index adb518d11..2a70d4bfe 100644 --- a/packages/css_designer/components/ui.json +++ b/packages/css_designer/components/ui.json @@ -53,8 +53,8 @@ } }, "scripts": { - "onInit": "init.lua", - "onSave": "export/to_scss.lua" + "onInit": "init.script", + "onSave": "export/to_scss.script" } }, { @@ -144,7 +144,7 @@ } }, "scripts": { - "onColorChange": "colors/color_picker.lua" + "onColorChange": "colors/color_picker.script" } }, { @@ -243,7 +243,7 @@ } }, "scripts": { - "onFontChange": "fonts/font_selector.lua" + "onFontChange": "fonts/font_selector.script" } }, { @@ -305,7 +305,7 @@ } }, "scripts": { - "onSpacingChange": "spacing/spacing_editor.lua" + "onSpacingChange": "spacing/spacing_editor.script" } }, { @@ -375,7 +375,7 @@ } }, "scripts": { - "onBorderChange": "borders/border_editor.lua" + "onBorderChange": "borders/border_editor.script" } }, { @@ -437,7 +437,7 @@ } }, "scripts": { - "onShadowChange": "shadows/shadow_editor.lua" + "onShadowChange": "shadows/shadow_editor.script" } }, { diff --git a/packages/css_designer/scripts/functions.json b/packages/css_designer/scripts/functions.json index 6df24e09b..891ac7ca3 100644 --- a/packages/css_designer/scripts/functions.json +++ b/packages/css_designer/scripts/functions.json @@ -2,7 +2,7 @@ "$schema": "https://metabuilder.dev/schemas/json-script.schema.json", "schemaVersion": "2.2.0", "package": "css_designer", - "description": "CSS Designer Lua functions for color manipulation, styling, and export", + "description": "CSS Designer script functions for color manipulation, styling, and export", "functions": [ { "id": "init", diff --git a/packages/dbal_demo/scripts/functions.json b/packages/dbal_demo/scripts/functions.json index 17967d1d5..90e431943 100644 --- a/packages/dbal_demo/scripts/functions.json +++ b/packages/dbal_demo/scripts/functions.json @@ -2,7 +2,7 @@ "$schema": "https://metabuilder.dev/schemas/json-script.schema.json", "schemaVersion": "2.2.0", "package": "dbal_demo", - "description": "DBAL Demo Lua functions for key-value store, blob storage, and cache operations", + "description": "DBAL Demo script functions for key-value store, blob storage, and cache operations", "functions": [ { "id": "init", diff --git a/packages/nerd_mode_ide/tests/metadata.params.json b/packages/nerd_mode_ide/tests/metadata.params.json index ff6d8d3a0..f72d98d79 100644 --- a/packages/nerd_mode_ide/tests/metadata.params.json +++ b/packages/nerd_mode_ide/tests/metadata.params.json @@ -9,7 +9,7 @@ { "path": "/index.ts", "language": "typescript" }, { "path": "/styles.css", "language": "css" }, { "path": "/data.json", "language": "json" }, - { "path": "/script.lua", "language": "lua" }, + { "path": "/script.script", "language": "script" }, { "path": "/README.md", "language": "markdown" } ], "gitOperations": [ diff --git a/packages/package_validator/package.json b/packages/package_validator/package.json index 219e53ece..1fc434fcd 100644 --- a/packages/package_validator/package.json +++ b/packages/package_validator/package.json @@ -77,9 +77,9 @@ }, "runtime": { "scripts": [ - "scripts/validator.lua" + "scripts/functions.json" ], - "main": "scripts/init.lua" + "main": "scripts/functions.json" }, "tests": { "suites": [ diff --git a/packages/package_validator/scripts/functions.json b/packages/package_validator/scripts/functions.json index 781b39277..19ab4a63b 100644 --- a/packages/package_validator/scripts/functions.json +++ b/packages/package_validator/scripts/functions.json @@ -21,7 +21,7 @@ "name": "options", "type": "object", "required": false, - "description": "Validation options (skipStructure, skipLua, skipStyles)" + "description": "Validation options (skipStructure, skipScripts, skipStyles)" } ], "returns": { @@ -52,7 +52,7 @@ "id": "validate_scripts", "name": "validateScripts", "exported": true, - "description": "Validates Lua scripts structure and exports", + "description": "Validates script structure and exports", "category": "validation", "parameters": [ { @@ -195,17 +195,17 @@ } }, { - "id": "check_lua_quality", - "name": "checkLuaQuality", + "id": "check_script_quality", + "name": "checkScriptQuality", "exported": true, - "description": "Checks Lua code quality and best practices", + "description": "Checks script code quality and best practices", "category": "validation", "parameters": [ { - "name": "luaCode", + "name": "scriptCode", "type": "string", "required": true, - "description": "Lua source code to check" + "description": "Script source code to check" } ], "returns": { @@ -225,7 +225,7 @@ "validateStorybook", "validateStyles", "formatResults", - "checkLuaQuality" + "checkScriptQuality" ] } } diff --git a/packages/package_validator/storybook/stories.json b/packages/package_validator/storybook/stories.json index ef7ba58d3..9bd825b55 100644 --- a/packages/package_validator/storybook/stories.json +++ b/packages/package_validator/storybook/stories.json @@ -39,7 +39,7 @@ { "name": "Validate Scripts", "render": "validate_scripts", - "description": "Validate Lua scripts and exports", + "description": "Validate script definitions and exports", "type": "function", "args": { "packagePath": "packages/json_script_example" diff --git a/packages/testing/components/ui.json b/packages/testing/components/ui.json index b5e1e209f..90dcac034 100644 --- a/packages/testing/components/ui.json +++ b/packages/testing/components/ui.json @@ -1,13 +1,13 @@ { "$schema": "https://metabuilder.dev/schemas/json-script-components.schema.json", "schemaVersion": "2.0.0", - "package": "lua_test", - "description": "Lua testing framework UI components for test execution and results display", + "package": "testing", + "description": "JSON testing framework UI components for test execution and results display", "components": [ { "id": "test_runner", "name": "TestRunner", - "description": "Interactive test runner component for executing Lua tests", + "description": "Interactive test runner component for executing script tests", "props": [ { "name": "packageId", diff --git a/packages/testing/package.json b/packages/testing/package.json index df1eb7adb..e2c2b6c65 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -34,13 +34,8 @@ ] }, "tests": { - "scripts": [ - "tests/metadata.test.lua" - ], - "parameterized": [ - { - "parameters": "tests/metadata.cases.json" - } + "suites": [ + "tests/metadata.test.json" ] } } diff --git a/packages/testing/permissions/roles.json b/packages/testing/permissions/roles.json index 69bb89377..c47d0b049 100644 --- a/packages/testing/permissions/roles.json +++ b/packages/testing/permissions/roles.json @@ -1,41 +1,41 @@ { "$schema": "https://metabuilder.dev/schemas/permissions.schema.json", "schemaVersion": "1.0.0", - "package": "lua_test", - "description": "Lua test framework access permissions", + "package": "testing", + "description": "JSON test framework access permissions", "permissions": [ { - "id": "lua.test.run", - "name": "Run Lua Tests", - "description": "Execute Lua test suites", - "resource": "lua_test", + "id": "testing.run", + "name": "Run Tests", + "description": "Execute JSON-based test suites", + "resource": "testing", "action": "execute", "scope": "global", "minLevel": 3 }, { - "id": "lua.test.view", + "id": "testing.view", "name": "View Test Results", - "description": "View test results and reports", - "resource": "lua_test", + "description": "View execution results and reports", + "resource": "testing", "action": "read", "scope": "global", "minLevel": 3 }, { - "id": "lua.test.configure", + "id": "testing.configure", "name": "Configure Test Runner", - "description": "Configure test runner settings and filters", - "resource": "lua_test", + "description": "Adjust test runner settings and filters", + "resource": "testing", "action": "manage", "scope": "global", "minLevel": 4 }, { - "id": "lua.test.debug", + "id": "testing.debug", "name": "Debug Tests", - "description": "Access detailed debug output and error traces", - "resource": "lua_test", + "description": "Access detailed execution traces", + "resource": "testing", "action": "execute", "scope": "global", "minLevel": 4 @@ -43,11 +43,15 @@ ], "resources": [ { - "id": "lua_test", - "name": "Lua Test Framework", + "id": "testing", + "name": "JSON Test Framework", "type": "function", - "description": "Lua unit testing framework resources", - "actions": ["read", "execute", "manage"] + "description": "Resources for JSON test execution", + "actions": [ + "read", + "execute", + "manage" + ] } ] } diff --git a/packages/testing/scripts/functions.json b/packages/testing/scripts/functions.json index 2a6e37da6..695a9e5db 100644 --- a/packages/testing/scripts/functions.json +++ b/packages/testing/scripts/functions.json @@ -1,8 +1,8 @@ { "$schema": "https://metabuilder.dev/schemas/json-script.schema.json", "schemaVersion": "2.2.0", - "package": "lua_test", - "description": "Lua unit testing framework functions including assertions, mocks, and test runner", + "package": "testing", + "description": "JSON-based testing framework functions including assertions, mocks, and test runner", "functions": [ { "id": "framework_load_cases", diff --git a/packages/testing/storybook/stories.json b/packages/testing/storybook/stories.json index 6cf2dc0c0..834622b8b 100644 --- a/packages/testing/storybook/stories.json +++ b/packages/testing/storybook/stories.json @@ -1,13 +1,13 @@ { "$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json", "featured": false, - "title": "Lua Test Framework", - "description": "Unit testing framework components for Lua scripts", + "title": "Script Test Framework", + "description": "Unit testing framework components for script suites", "stories": [ { "name": "TestRunner", "render": "framework", - "description": "Interactive test runner for executing Lua test suites", + "description": "Interactive test runner for executing script suites", "args": { "packageId": "dashboard", "autoRun": false, diff --git a/packages/testing/tests/metadata.test.json b/packages/testing/tests/metadata.test.json new file mode 100644 index 000000000..5642a3a0c --- /dev/null +++ b/packages/testing/tests/metadata.test.json @@ -0,0 +1,70 @@ +{ + "$schema": "https://metabuilder.dev/schemas/tests.schema.json", + "schemaVersion": "2.0.0", + "package": "testing", + "description": "Metadata validation tests for the Testing Framework", + "testSuites": [ + { + "id": "metadata_validation", + "name": "Testing Framework Metadata", + "description": "Verify metadata integrity for the testing framework", + "tests": [ + { + "id": "package-id", + "name": "packageId matches", + "act": { + "type": "function_call", + "target": "getPackageMetadata", + "input": "testing" + }, + "assert": { + "expectations": [ + { + "type": "equals", + "actual": "result.packageId", + "expected": "testing" + } + ] + } + }, + { + "id": "icon-exists", + "name": "Icon exists", + "act": { + "type": "function_call", + "target": "checkFileExists", + "input": "testing/static_content/icon.svg" + }, + "assert": { + "expectations": [ + { + "type": "truthy", + "actual": "result" + } + ] + } + }, + { + "id": "metadata-schema", + "name": "package.json validates", + "act": { + "type": "function_call", + "target": "validateAgainstSchema", + "input": { + "file": "testing/package.json", + "schema": "https://metabuilder.dev/schemas/package-metadata.schema.json" + } + }, + "assert": { + "expectations": [ + { + "type": "truthy", + "actual": "result.valid" + } + ] + } + } + ] + } + ] +} diff --git a/packages/ui_home/components/ui.json b/packages/ui_home/components/ui.json index 4d5610306..7cad674db 100644 --- a/packages/ui_home/components/ui.json +++ b/packages/ui_home/components/ui.json @@ -428,7 +428,7 @@ "children": [{ "type": "Text", "children": "5" }] }, { "type": "Text", "variant": "h6", "children": "God-Tier Builder", "sx": { "fontWeight": 600 } }, - { "type": "Text", "variant": "body2", "children": "Meta-builder with workflows, schemas, and Lua scripting", "sx": { "color": "text.secondary", "mt": 1 } } + { "type": "Text", "variant": "body2", "children": "Meta-builder with workflows, schemas, and automation scripting", "sx": { "color": "text.secondary", "mt": 1 } } ] }, { diff --git a/packages/ui_level2/components/ui.json b/packages/ui_level2/components/ui.json index 1081c5b51..42dd0b6e7 100644 --- a/packages/ui_level2/components/ui.json +++ b/packages/ui_level2/components/ui.json @@ -292,8 +292,8 @@ "children": [ { "type": "ListItemText", - "primary": "Great article on Lua scripting!", - "secondary": "Posted 2 days ago on 'Getting Started with Lua'" + "primary": "Great article on automation scripting!", + "secondary": "Posted 2 days ago on 'Getting Started with Automation Scripts'" } ] }, diff --git a/packages/ui_level2/storybook/stories.json b/packages/ui_level2/storybook/stories.json index 4f2c9fec3..a0dba23b4 100644 --- a/packages/ui_level2/storybook/stories.json +++ b/packages/ui_level2/storybook/stories.json @@ -27,9 +27,9 @@ "comments": [ { "id": "1", - "text": "Great article on Lua scripting!", + "text": "Great article on automation scripting!", "timestamp": "2 days ago", - "topic": "Getting Started with Lua" + "topic": "Getting Started with Automation Scripts" }, { "id": "2", diff --git a/packages/ui_level4/components/ui.json b/packages/ui_level4/components/ui.json index ae5650529..7a96c5684 100644 --- a/packages/ui_level4/components/ui.json +++ b/packages/ui_level4/components/ui.json @@ -20,7 +20,7 @@ "type": "boolean", "required": false, "default": false, - "description": "Whether nerd mode (schema/Lua) is enabled" + "description": "Whether nerd mode (schema/scripts) is enabled" } ], "render": { @@ -129,7 +129,7 @@ "props": { "eyebrow": "Level 4", "title": "Application Builder", - "description": "{{nerdMode ? 'Design declaratively with schemas and Lua scripts.' : 'Build visually with forms and drag-and-drop.'}}" + "description": "{{nerdMode ? 'Design declaratively with schemas and automation scripts.' : 'Build visually with forms and drag-and-drop.'}}" } }, "{{children}}" @@ -142,7 +142,7 @@ { "id": "level4_tabs", "name": "Level4Tabs", - "description": "Tabbed interface for Schemas, Workflows, and Lua Scripts", + "description": "Tabbed interface for Schemas, Workflows, and Scripts", "props": [ { "name": "defaultTab", @@ -157,32 +157,32 @@ "className": "tabs-container", "defaultValue": "{{defaultTab}}", "children": [ - { - "type": "TabsList", - "children": [ { - "type": "TabsTrigger", - "props": { - "value": "schemas", - "text": "Schemas" - } + "type": "TabsList", + "children": [ + { + "type": "TabsTrigger", + "props": { + "value": "schemas", + "text": "Schemas" + } + }, + { + "type": "TabsTrigger", + "props": { + "value": "workflows", + "text": "Workflows" + } + }, + { + "type": "TabsTrigger", + "props": { + "value": "scripts", + "text": "Scripts" + } + } + ] }, - { - "type": "TabsTrigger", - "props": { - "value": "workflows", - "text": "Workflows" - } - }, - { - "type": "TabsTrigger", - "props": { - "value": "lua", - "text": "Lua Scripts" - } - } - ] - }, { "type": "TabsContent", "value": "schemas", @@ -203,10 +203,10 @@ }, { "type": "TabsContent", - "value": "lua", + "value": "scripts", "children": [ { - "type": "LuaScriptsTab" + "type": "ScriptsTab" } ] } diff --git a/packages/ui_level4/package.json b/packages/ui_level4/package.json index 59d91e17e..35382093b 100644 --- a/packages/ui_level4/package.json +++ b/packages/ui_level4/package.json @@ -3,7 +3,7 @@ "packageId": "ui_level4", "name": "Level 4 - Admin Panel", "version": "1.0.0", - "description": "Admin panel for user and system management with schemas, workflows, and Lua scripts", + "description": "Admin panel for user and system management with schemas, workflows, and automated scripts", "author": "MetaBuilder", "license": "MIT", "category": "ui", @@ -26,7 +26,7 @@ "Level4Layout", "SchemasTab", "WorkflowsTab", - "LuaScriptsTab", + "ScriptsTab", "GodSidebar", "GodToolbar", "GodContent" diff --git a/packages/ui_level4/permissions/roles.json b/packages/ui_level4/permissions/roles.json index 5fe2ad337..fbe17b062 100644 --- a/packages/ui_level4/permissions/roles.json +++ b/packages/ui_level4/permissions/roles.json @@ -68,10 +68,10 @@ "minLevel": 4 }, { - "id": "level4.lua.edit", - "name": "Edit Lua Scripts", - "description": "Create and modify Lua scripts", - "resource": "level4.lua", + "id": "level4.scripts.edit", + "name": "Edit Scripts", + "description": "Create and modify automation scripts", + "resource": "level4.scripts", "action": "update", "scope": "global", "minLevel": 4 @@ -114,10 +114,10 @@ "actions": ["read", "update", "execute"] }, { - "id": "level4.lua", - "name": "Lua Scripts", + "id": "level4.scripts", + "name": "Scripts", "type": "function", - "description": "Lua script definitions", + "description": "Automation script definitions", "actions": ["read", "update", "execute"] } ] diff --git a/packages/ui_level4/scripts/functions.json b/packages/ui_level4/scripts/functions.json index 7022e57ec..b9cc74fee 100644 --- a/packages/ui_level4/scripts/functions.json +++ b/packages/ui_level4/scripts/functions.json @@ -22,7 +22,7 @@ "id": "layout_tabs", "name": "tabs", "exported": true, - "description": "Render tabbed interface for Schemas, Workflows, and Lua Scripts", + "description": "Render tabbed interface for Schemas, Workflows, and Scripts", "category": "layout" }, { diff --git a/packages/ui_level4/storybook/stories.json b/packages/ui_level4/storybook/stories.json index 23e5d84ec..facf3c562 100644 --- a/packages/ui_level4/storybook/stories.json +++ b/packages/ui_level4/storybook/stories.json @@ -2,7 +2,7 @@ "$schema": "https://metabuilder.dev/schemas/package-storybook.schema.json", "featured": true, "title": "Level 4 Admin Panel", - "description": "Admin panel components for schemas, workflows, and Lua scripts management", + "description": "Admin panel components for schemas, workflows, and script automation management", "stories": [ { "name": "AdminPanel", diff --git a/schemas/package-schemas/metadata_schema.json b/schemas/package-schemas/metadata_schema.json index 68fc53152..3ad4907a7 100644 --- a/schemas/package-schemas/metadata_schema.json +++ b/schemas/package-schemas/metadata_schema.json @@ -216,8 +216,14 @@ "type": "object", "description": "Script executor paths", "properties": { - "lua": { "type": "string" }, - "javascript": { "type": "string" } + "jsonScript": { + "type": "string", + "description": "Path to the JSON script entry point" + }, + "javascript": { + "type": "string", + "description": "Path to a JavaScript shim or helper" + } } }, "description": { diff --git a/scripts/generate-package.ts b/scripts/generate-package.ts index d271055dc..133d76713 100644 --- a/scripts/generate-package.ts +++ b/scripts/generate-package.ts @@ -145,14 +145,13 @@ function generateMetadata(config: PackageConfig): string { category: config.category, primary: config.primary, dependencies: config.dependencies, - devDependencies: ['lua_test'], + devDependencies: ['testing'], exports: { components: config.components, - scripts: ['init'] + scripts: ['lifecycle'] }, tests: { - scripts: ['tests/metadata.test.lua', 'tests/components.test.lua'], - cases: ['tests/metadata.cases.json', 'tests/components.cases.json'] + scripts: ['tests/metadata.test.json'] }, minLevel: config.minLevel, ...(config.withSchema && config.entities.length > 0 ? { @@ -167,60 +166,163 @@ function generateMetadata(config: PackageConfig): string { return JSON.stringify(metadata, null, 2) } -function generateInitLua(config: PackageConfig): string { - return `--- ${config.name} initialization ---- @module init - -local M = {} - ----@class InstallContext ----@field version string - ----@class InstallResult ----@field message string ----@field version string - ----Called when package is installed ----@param context InstallContext ----@return InstallResult -function M.on_install(context) - return { - message = "${config.name} installed successfully", - version = context.version +function generateLifecycleScript(config: PackageConfig): string { + const script = { + $schema: 'https://metabuilder.dev/schemas/json-script.schema.json', + schemaVersion: '2.2.0', + package: config.packageId, + description: `${config.name} lifecycle hooks`, + functions: [ + { + id: 'on_install', + name: 'onInstall', + exported: true, + category: 'lifecycle', + description: 'Called when the package is installed', + params: [ + { + name: 'context', + type: 'object', + description: 'Installation context' + } + ], + returnType: 'object', + body: [ + { + type: 'return', + value: { + type: 'object_literal', + properties: [ + { + key: 'message', + value: { + type: 'literal', + value: `${config.name} installed successfully` + } + }, + { + key: 'version', + value: { + type: 'member_access', + object: { type: 'identifier', name: 'context' }, + property: 'version' + } + } + ] + } + } + ] + }, + { + id: 'on_uninstall', + name: 'onUninstall', + exported: true, + category: 'lifecycle', + description: 'Called when the package is uninstalled', + returnType: 'object', + body: [ + { + type: 'return', + value: { + type: 'object_literal', + properties: [ + { + key: 'message', + value: { + type: 'literal', + value: `${config.name} removed` + } + } + ] + } + } + ] + } + ], + exports: { + functions: ['onInstall', 'onUninstall'] + } } -end ----Called when package is uninstalled ----@return table -function M.on_uninstall() - return { message = "${config.name} removed" } -end - -return M -` + return JSON.stringify(script, null, 2) } -function generateTestLua(testName: string, config: PackageConfig): string { - return `-- ${testName} tests for ${config.packageId} +function generateMetadataTestJson(config: PackageConfig): string { + const tests = { + $schema: 'https://metabuilder.dev/schemas/tests.schema.json', + schemaVersion: '2.0.0', + package: config.packageId, + description: `Metadata validation tests for ${config.name}`, + testSuites: [ + { + id: 'metadata_validation', + name: `${config.name} Metadata`, + description: 'Verify package metadata integrity', + tests: [ + { + id: 'package-id', + name: 'packageId matches', + act: { + type: 'function_call', + target: 'getPackageMetadata', + input: config.packageId + }, + assert: { + expectations: [ + { + type: 'equals', + actual: 'result.packageId', + expected: config.packageId, + description: 'packageId comes from directory name' + } + ] + } + }, + { + id: 'icon-exists', + name: 'Icon exists', + act: { + type: 'function_call', + target: 'checkFileExists', + input: `${config.packageId}/static_content/icon.svg` + }, + assert: { + expectations: [ + { + type: 'truthy', + actual: 'result', + description: 'Icon file is present' + } + ] + } + }, + { + id: 'metadata-schema', + name: 'package.json validates', + act: { + type: 'function_call', + target: 'validateAgainstSchema', + input: { + file: `${config.packageId}/package.json`, + schema: 'https://metabuilder.dev/schemas/package-metadata.schema.json' + } + }, + assert: { + expectations: [ + { + type: 'truthy', + actual: 'result.valid', + description: 'package.json conforms to metadata schema' + } + ] + } + } + ] + } + ] + } -describe("${config.name} - ${testName}", function() - it("should pass basic validation", function() - expect(true).toBe(true) - end) - - it("should have required fields", function() - -- TODO: Add specific tests - expect(true).toBe(true) - end) -end) -` -} - -function generateTestCases(): string { - return JSON.stringify([ - { name: 'valid_input', input: {}, expected: { valid: true } }, - { name: 'invalid_input', input: { invalid: true }, expected: { valid: false } } - ], null, 2) + return JSON.stringify(tests, null, 2) } function generateSchemaYaml(config: PackageConfig): string { @@ -266,83 +368,6 @@ function generateSchemaYaml(config: PackageConfig): string { return lines.join('\n') } -function generateDbOperations(config: PackageConfig): string { - const lines = [ - `-- Database operations for ${config.name}`, - '-- Auto-generated by package template generator', - '', - 'local M = {}', - '' - ] - - for (const entity of config.entities) { - const entityLower = entity.toLowerCase() - - lines.push(`-- ${entity} operations`) - lines.push('') - lines.push(`---List all ${entity} records`) - lines.push('---@param ctx DBALContext') - lines.push('---@return table[]') - lines.push(`function M.list_${entityLower}(ctx)`) - lines.push(' -- List operation template - customize query as needed') - lines.push(` local result = ctx.db:query("SELECT * FROM ${entityLower} WHERE tenantId = ?", {ctx.tenantId})`) - lines.push(' return result or {}') - lines.push('end') - lines.push('') - lines.push(`---Get a single ${entity} by ID`) - lines.push('---@param ctx DBALContext') - lines.push('---@param id string') - lines.push('---@return table|nil') - lines.push(`function M.get_${entityLower}(ctx, id)`) - lines.push(' -- Get operation template - customize query as needed') - lines.push(` local result = ctx.db:queryOne("SELECT * FROM ${entityLower} WHERE id = ? AND tenantId = ?", {id, ctx.tenantId})`) - lines.push(' return result') - lines.push('end') - lines.push('') - lines.push(`---Create a new ${entity}`) - lines.push('---@param ctx DBALContext') - lines.push('---@param data table') - lines.push('---@return table') - lines.push(`function M.create_${entityLower}(ctx, data)`) - lines.push(' -- Create operation template - customize fields as needed') - lines.push(' data.id = data.id or ctx.generateId()') - lines.push(' data.tenantId = ctx.tenantId') - lines.push(' data.createdAt = os.time()') - lines.push(' data.updatedAt = os.time()') - lines.push(` ctx.db:insert("${entityLower}", data)`) - lines.push(' return data') - lines.push('end') - lines.push('') - lines.push(`---Update an existing ${entity}`) - lines.push('---@param ctx DBALContext') - lines.push('---@param id string') - lines.push('---@param data table') - lines.push('---@return table|nil') - lines.push(`function M.update_${entityLower}(ctx, id, data)`) - lines.push(' -- Update operation template - customize fields as needed') - lines.push(' data.updatedAt = os.time()') - lines.push(` local success = ctx.db:update("${entityLower}", id, data, {tenantId = ctx.tenantId})`) - lines.push(' if success then') - lines.push(` return M.get_${entityLower}(ctx, id)`) - lines.push(' end') - lines.push(' return nil') - lines.push('end') - lines.push('') - lines.push(`---Delete a ${entity}`) - lines.push('---@param ctx DBALContext') - lines.push('---@param id string') - lines.push('---@return boolean') - lines.push(`function M.delete_${entityLower}(ctx, id)`) - lines.push(' -- Delete operation template - customize as needed') - lines.push(` return ctx.db:delete("${entityLower}", id, {tenantId = ctx.tenantId})`) - lines.push('end') - lines.push('') - } - - lines.push('return M') - return lines.join('\n') -} - function generateComponentsJson(config: PackageConfig): string { const components = config.components.map(name => ({ id: `${config.packageId}_${name.toLowerCase()}`, @@ -467,21 +492,17 @@ function generate(config: PackageConfig): GeneratedFile[] { files.push({ path: 'seed/metadata.json', content: generateMetadata(config) }) files.push({ path: 'seed/components.json', content: generateComponentsJson(config) }) files.push({ path: 'seed/layout.json', content: generateLayoutJson(config) }) - files.push({ path: 'seed/scripts/init.lua', content: generateInitLua(config) }) + files.push({ path: 'seed/scripts/functions.json', content: generateLifecycleScript(config) }) files.push({ path: 'seed/index.ts', content: generateIndexTs(config) }) // Schema files if (config.withSchema && config.entities.length > 0) { files.push({ path: 'seed/schema/entities.yaml', content: generateSchemaYaml(config) }) - files.push({ path: 'seed/scripts/db/operations.lua', content: generateDbOperations(config) }) } // Test files if (config.withTests) { - files.push({ path: 'seed/scripts/tests/metadata.test.lua', content: generateTestLua('metadata', config) }) - files.push({ path: 'seed/scripts/tests/components.test.lua', content: generateTestLua('components', config) }) - files.push({ path: 'seed/scripts/tests/metadata.cases.json', content: generateTestCases() }) - files.push({ path: 'seed/scripts/tests/components.cases.json', content: generateTestCases() }) + files.push({ path: 'seed/tests/metadata.test.json', content: generateMetadataTestJson(config) }) } // Static content diff --git a/seed/LANDING_PAGE_VERIFICATION.md b/seed/LANDING_PAGE_VERIFICATION.md index 2a04f05b8..c98423b9c 100644 --- a/seed/LANDING_PAGE_VERIFICATION.md +++ b/seed/LANDING_PAGE_VERIFICATION.md @@ -294,13 +294,15 @@ Before deploying, verify: ### 1. Check Package Installation ```bash -# Via CLI docker-compose -f deployment/docker/docker-compose.production.yml \ - run --rm metabuilder-tools \ - metabuilder-cli package list | grep ui_home + exec postgres \ + psql -U metabuilder metabuilder -c \ + "SELECT \"packageId\", enabled FROM \"InstalledPackage\" WHERE \"packageId\" = 'ui_home';" # Expected output: -# ✓ ui_home (v1.0.0) - Home Page [INSTALLED] [ENABLED] +# packageId | enabled +# -----------+--------- +# ui_home | t ``` ### 2. Check Database Records @@ -341,7 +343,10 @@ open http://localhost:3000/ **Check 1**: Package installed? ```bash -metabuilder-cli package list | grep ui_home +docker-compose -f deployment/docker/docker-compose.production.yml \ + exec postgres \ + psql -U metabuilder metabuilder -c \ + "SELECT \"packageId\", enabled FROM \"InstalledPackage\" WHERE \"packageId\" = 'ui_home';" ``` **Check 2**: Database record exists? diff --git a/spec/README.md b/spec/README.md index 86419f093..ed88dd086 100644 --- a/spec/README.md +++ b/spec/README.md @@ -220,7 +220,7 @@ schemas/package-schemas/ ├── metadata_schema.json → Package identity, version, minLevel ├── entities_schema.json → Database entities (Prisma-like) ├── components_schema.json → UI component definitions -├── script_schema.json → Lua/JSON script logic +├── script_schema.json → Script/JSON script logic ├── types_schema.json → Type definitions ├── validation_schema.json → Data validators ├── api_schema.json → REST/GraphQL endpoints @@ -240,7 +240,7 @@ schemas/package-schemas/ packages/{name}/ ├── package.json # Metadata (validated against metadata_schema.json) ├── components/ # UI components -├── scripts/ # Lua/JSON scripts +├── scripts/ # Script/JSON scripts ├── permissions/ # Permission definitions ├── static_content/ # Assets including icon.svg ├── styles/ # SCSS/design tokens diff --git a/storybook/README.md b/storybook/README.md index 90972e022..448fd7cd0 100644 --- a/storybook/README.md +++ b/storybook/README.md @@ -1,6 +1,6 @@ -# MetaBuilder Lua Package Storybook +# MetaBuilder Package Storybook -A standalone Storybook for previewing Lua packages from MetaBuilder without running the full application. +A standalone Storybook for previewing MetaBuilder packages powered by JSON scripts without running the full application. ## Quick Start @@ -19,12 +19,12 @@ Packages are automatically discovered from `packages/index.json` based on `story ```json { - "discovery": { - "includedCategories": ["ui", "admin", "gaming", "social", "editors"], - "excludedPackages": ["shared", "lua_test"], - "minLevel": 1, - "maxLevel": 6 - } + "discovery": { + "includedCategories": ["ui", "admin", "gaming", "social", "editors"], + "excludedPackages": ["shared", "testing"], + "minLevel": 1, + "maxLevel": 6 + } } ``` diff --git a/storybook/package.json b/storybook/package.json index d5b77cb28..1838dd7ac 100644 --- a/storybook/package.json +++ b/storybook/package.json @@ -2,7 +2,7 @@ "name": "@metabuilder/storybook", "version": "1.0.0", "private": true, - "description": "Storybook for rendering Lua packages and UI components", + "description": "Storybook for rendering MetaBuilder JSON packages and UI components", "type": "module", "scripts": { "dev": "storybook dev -p 6006", diff --git a/storybook/public/storybook.config.json b/storybook/public/storybook.config.json index a1a4a8373..9a7d1a92d 100644 --- a/storybook/public/storybook.config.json +++ b/storybook/public/storybook.config.json @@ -1,6 +1,6 @@ { "$schema": "./storybook-config.schema.json", - "description": "Auto-discovery configuration for Lua package Storybook", + "description": "Auto-discovery configuration for the MetaBuilder package Storybook", "packagesPath": "../packages", "packagesIndex": "../packages/index.json", @@ -8,7 +8,7 @@ "enabled": true, "scanManifests": true, "includedCategories": ["ui", "admin", "gaming", "social", "editors"], - "excludedPackages": ["shared", "lua_test"], + "excludedPackages": ["shared", "testing"], "minLevel": 1, "maxLevel": 6 }, diff --git a/storybook/src/components/registry.tsx b/storybook/src/components/registry.tsx index 697b4e9de..b7ca3a371 100644 --- a/storybook/src/components/registry.tsx +++ b/storybook/src/components/registry.tsx @@ -359,7 +359,7 @@ export const Chip: React.FC = ({ {label || children} ) -// Placeholder components for complex Lua package components +// Placeholder components for complex script package components export const Level4Header: React.FC = ({ username = 'User', nerdMode = false, @@ -883,7 +883,7 @@ export const Pagination: React.FC = { DialogContent, DialogActions, - // App-specific (from Lua packages) + // App-specific (from packages) Level4Header, IntroSection, AppHeader, @@ -980,7 +980,7 @@ export const componentRegistry: Record = { } /** - * Get a component by its Lua type name + * Get a component by its package type name */ export function getComponent(typeName: string): AnyComponent | undefined { return componentRegistry[typeName] diff --git a/storybook/src/mocks/data/dashboard.json b/storybook/src/mocks/data/dashboard.json index bd18491a7..5a46a820b 100644 --- a/storybook/src/mocks/data/dashboard.json +++ b/storybook/src/mocks/data/dashboard.json @@ -12,17 +12,17 @@ } }, "renders": { - "init.lua": { + "init.script": { "description": "Lifecycle hooks - no visual render", "component": { "type": "Alert", "props": { "severity": "info" }, "children": [ - { "type": "Typography", "props": { "variant": "body2", "text": "init.lua contains lifecycle hooks (on_install, on_update) - no visual render" } } + { "type": "Typography", "props": { "variant": "body2", "text": "init.script contains lifecycle hooks (on_install, on_update) - no visual render" } } ] } }, - "stats.lua": { + "stats.script": { "description": "Statistics grid with metric cards", "component": { "type": "Grid", @@ -95,7 +95,7 @@ ] } }, - "layout.lua": { + "layout.script": { "description": "Standard dashboard layout with header", "component": { "type": "Box", diff --git a/storybook/src/mocks/data/data_table.json b/storybook/src/mocks/data/data_table.json index 3000c0fdc..189bae414 100644 --- a/storybook/src/mocks/data/data_table.json +++ b/storybook/src/mocks/data/data_table.json @@ -12,17 +12,17 @@ } }, "renders": { - "init.lua": { + "init.script": { "description": "Lifecycle hooks", "component": { "type": "Alert", "props": { "severity": "info" }, "children": [ - { "type": "Typography", "props": { "text": "init.lua - lifecycle hooks" } } + { "type": "Typography", "props": { "text": "init.script - lifecycle hooks" } } ] } }, - "render_table.lua": { + "render_table.script": { "description": "Data table with pagination", "component": { "type": "Card", diff --git a/storybook/src/mocks/data/nav_menu.json b/storybook/src/mocks/data/nav_menu.json index d5f331526..f082fcbbf 100644 --- a/storybook/src/mocks/data/nav_menu.json +++ b/storybook/src/mocks/data/nav_menu.json @@ -11,17 +11,17 @@ } }, "renders": { - "init.lua": { + "init.script": { "description": "Lifecycle hooks", "component": { "type": "Alert", "props": { "severity": "info" }, "children": [ - { "type": "Typography", "props": { "text": "init.lua - lifecycle hooks" } } + { "type": "Typography", "props": { "text": "init.script - lifecycle hooks" } } ] } }, - "sidebar.lua": { + "sidebar.script": { "description": "Sidebar navigation", "component": { "type": "Box", @@ -105,7 +105,7 @@ ] } }, - "navbar.lua": { + "navbar.script": { "description": "Top navigation bar", "component": { "type": "AppBar", diff --git a/storybook/src/mocks/data/ui_level4.json b/storybook/src/mocks/data/ui_level4.json index accdafe64..ec053365f 100644 --- a/storybook/src/mocks/data/ui_level4.json +++ b/storybook/src/mocks/data/ui_level4.json @@ -13,17 +13,17 @@ } }, "renders": { - "init.lua": { + "init.script": { "description": "Lifecycle hooks", "component": { "type": "Alert", "props": { "severity": "info" }, "children": [ - { "type": "Typography", "props": { "variant": "body2", "text": "init.lua contains lifecycle hooks - no visual render" } } + { "type": "Typography", "props": { "variant": "body2", "text": "init.script contains lifecycle hooks - no visual render" } } ] } }, - "layout.lua": { + "layout.script": { "description": "Main admin panel layout", "component": { "type": "Box", @@ -61,7 +61,7 @@ ] } }, - "schemas.lua": { + "schemas.script": { "description": "Schema editor interface", "component": { "type": "Stack", @@ -88,7 +88,7 @@ ] } }, - "workflows.lua": { + "workflows.script": { "description": "Workflow designer interface", "component": { "type": "Stack", diff --git a/storybook/src/mocks/data/ui_login.json b/storybook/src/mocks/data/ui_login.json index 70b31b52f..dcc37d87e 100644 --- a/storybook/src/mocks/data/ui_login.json +++ b/storybook/src/mocks/data/ui_login.json @@ -11,7 +11,7 @@ } }, "renders": { - "login_form.lua": { + "login_form.script": { "description": "Login form", "component": { "type": "Box", @@ -44,7 +44,7 @@ }] } }, - "register_form.lua": { + "register_form.script": { "description": "Registration form", "component": { "type": "Box", diff --git a/storybook/src/mocks/data/user_manager.json b/storybook/src/mocks/data/user_manager.json index c366070c7..447d21d87 100644 --- a/storybook/src/mocks/data/user_manager.json +++ b/storybook/src/mocks/data/user_manager.json @@ -11,17 +11,17 @@ } }, "renders": { - "init.lua": { + "init.script": { "description": "Lifecycle hooks", "component": { "type": "Alert", "props": { "severity": "info" }, "children": [ - { "type": "Typography", "props": { "variant": "body2", "text": "init.lua contains lifecycle hooks - no visual render" } } + { "type": "Typography", "props": { "variant": "body2", "text": "init.script contains lifecycle hooks - no visual render" } } ] } }, - "render_users.lua": { + "render_users.script": { "description": "User management table", "component": { "type": "Card", @@ -60,7 +60,7 @@ ] } }, - "list.lua": { + "list.script": { "description": "Simple user list", "component": { "type": "Stack", @@ -73,7 +73,7 @@ ] } }, - "create_user.lua": { + "create_user.script": { "description": "Create user form", "component": { "type": "Card", diff --git a/storybook/src/mocks/json-loader.ts b/storybook/src/mocks/json-loader.ts index 7c71c351b..47a21cf0f 100644 --- a/storybook/src/mocks/json-loader.ts +++ b/storybook/src/mocks/json-loader.ts @@ -1,18 +1,14 @@ /** * JSON Mock Loader - * + * * Loads mock package definitions from JSON files in the data/ directory. * No manual TypeScript registration needed - just add a JSON file! */ -import type { LuaRenderContext, LuaUIComponent } from '../types/lua-types' -import type { MockLuaResult, MockPackageDefinition } from './lua-engine' -import { registerMockPackage } from './lua-engine' import type { JsonMockPackage, TemplateVariables } from './schema' import { processTemplates } from './schema' -// Import all JSON mock files -// Vite handles JSON imports natively +// Import all JSON mock files (Vite handles JSON imports natively) import dashboardMock from './data/dashboard.json' import dataTableMock from './data/data_table.json' import navMenuMock from './data/nav_menu.json' @@ -20,93 +16,107 @@ import uiLevel4Mock from './data/ui_level4.json' import uiLoginMock from './data/ui_login.json' import userManagerMock from './data/user_manager.json' -/** - * Convert a JSON mock package to a runtime MockPackageDefinition - */ -function jsonToMockPackage(json: JsonMockPackage): MockPackageDefinition { - const renders: Record LuaUIComponent> = {} - - for (const [scriptName, render] of Object.entries(json.renders)) { - renders[scriptName] = (ctx: LuaRenderContext) => { - // Build template variables from context - const variables: TemplateVariables = { - 'user.username': ctx.user?.username ?? 'Guest', - 'user.email': ctx.user?.email ?? 'guest@example.com', - 'user.level': ctx.user?.level ?? 1, - 'user.id': ctx.user?.id ?? 'guest', - 'tenant.name': ctx.tenant?.name ?? 'Default', - 'tenant.id': ctx.tenant?.id ?? 'default', - 'nerdMode': ctx.nerdMode ?? false, - 'theme': ctx.theme ?? 'light', - } - - // Process templates and return component - return processTemplates(render.component, variables) - } +export interface RenderContext { + user?: { + id?: string + username?: string + email?: string + level?: number } - - return { - metadata: json.metadata, - renders, + tenant?: { + id?: string + name?: string } + nerdMode?: boolean + theme?: string } -/** - * All JSON mock packages - */ -const jsonMocks: JsonMockPackage[] = [ - dashboardMock as unknown as JsonMockPackage, - dataTableMock as unknown as JsonMockPackage, - navMenuMock as unknown as JsonMockPackage, - uiLevel4Mock as unknown as JsonMockPackage, - uiLoginMock as unknown as JsonMockPackage, - userManagerMock as unknown as JsonMockPackage, -] +export interface MockResult { + success: boolean + result?: Record + error?: string + logs: string[] +} + +export interface MockPackageDefinition { + metadata: JsonMockPackage['metadata'] + renders: Record +} + +export interface JsonMockRender { + component: JsonMockPackage['renders'][string]['component'] + description?: string +} + +const mockPackages = new Map() + +export function registerMockPackage(pkg: MockPackageDefinition): void { + if (!pkg.metadata?.packageId) return + mockPackages.set(pkg.metadata.packageId, pkg) +} + +export function getMockPackage(packageId: string): MockPackageDefinition | undefined { + return mockPackages.get(packageId) +} + +export function listMockPackages(): MockPackageDefinition[] { + return Array.from(mockPackages.values()) +} -/** - * Register all JSON mocks - * Call this once at startup - */ export function registerJsonMocks(): void { + const jsonMocks: JsonMockPackage[] = [ + dashboardMock as unknown as JsonMockPackage, + dataTableMock as unknown as JsonMockPackage, + navMenuMock as unknown as JsonMockPackage, + uiLevel4Mock as unknown as JsonMockPackage, + uiLoginMock as unknown as JsonMockPackage, + userManagerMock as unknown as JsonMockPackage, + ] + for (const json of jsonMocks) { - const pkg = jsonToMockPackage(json) + const pkg: MockPackageDefinition = { + metadata: json.metadata, + renders: Object.fromEntries( + Object.entries(json.renders).map(([name, render]) => [ + name, + { + component: render.component, + description: render.description, + }, + ]) + ), + } registerMockPackage(pkg) } } -/** - * Get render descriptions for documentation - */ export function getRenderDescriptions(packageId: string): Record { - const json = jsonMocks.find(m => m.metadata.packageId === packageId) - if (!json) return {} + const pkg = getMockPackage(packageId) + if (!pkg) return {} const descriptions: Record = {} - for (const [name, render] of Object.entries(json.renders)) { + for (const [name, render] of Object.entries(pkg.renders)) { descriptions[name] = render.description || '' } return descriptions } -/** - * Execute a JSON mock render directly (for testing) - */ export function executeJsonMock( packageId: string, scriptName: string, - context: LuaRenderContext -): MockLuaResult { - const json = jsonMocks.find(m => m.metadata.packageId === packageId) - if (!json) { + context: RenderContext +): MockResult { + const pkg = getMockPackage(packageId) + if (!pkg) { return { success: false, error: `Package not found: ${packageId}`, logs: [] } } - const render = json.renders[scriptName] + const render = pkg.renders[scriptName] if (!render) { return { success: false, error: `Render not found: ${scriptName}`, - logs: [`Available: ${Object.keys(json.renders).join(', ')}`], + logs: [`Available: ${Object.keys(pkg.renders).join(', ')}`], } } @@ -121,9 +131,36 @@ export function executeJsonMock( 'theme': context.theme ?? 'light', } + const result = processTemplates(render.component, variables) + return { success: true, - result: processTemplates(render.component, variables), + result, logs: [], } } + +export function executeMockRender( + packageId: string, + scriptName: string, + context: RenderContext +): MockResult { + return executeJsonMock(packageId, scriptName, context) +} + +export function createDefaultContext(): RenderContext { + return { + user: { + id: 'guest', + username: 'guest', + email: 'guest@example.com', + level: 1, + }, + tenant: { + id: 'default', + name: 'Default Tenant', + }, + nerdMode: false, + theme: 'light', + } +} diff --git a/storybook/src/mocks/packages/index.ts b/storybook/src/mocks/packages/index.ts index 24962eb29..cf578a070 100644 --- a/storybook/src/mocks/packages/index.ts +++ b/storybook/src/mocks/packages/index.ts @@ -45,15 +45,15 @@ export async function initializeMocks(): Promise { } // Re-export utilities -export { - getMockPackage, - listMockPackages, +export { + getMockPackage, + listMockPackages, executeMockRender, createDefaultContext, -} from '../lua-engine' - -// Export JSON utilities -export { getRenderDescriptions, executeJsonMock } from '../json-loader' + registerJsonMocks, + getRenderDescriptions, + executeJsonMock, +} from '../json-loader' // Export auto-loader utilities export { autoLoadPackage, loadPackageComponents, loadPackageMetadata } from '../auto-loader' diff --git a/storybook/src/mocks/schema.ts b/storybook/src/mocks/schema.ts index 30c0b0822..3510ae792 100644 --- a/storybook/src/mocks/schema.ts +++ b/storybook/src/mocks/schema.ts @@ -1,11 +1,12 @@ /** * JSON Schema types for data-driven mock definitions - * + * * Mock packages are defined in JSON files and automatically loaded. * No TypeScript boilerplate needed - just define the component trees in JSON. */ -import type { LuaUIComponent, LuaPackageMetadata } from '../types/lua-types' +type PackageComponent = Record +type PackageMetadata = Record /** * A mock render definition in JSON format @@ -13,7 +14,7 @@ import type { LuaUIComponent, LuaPackageMetadata } from '../types/lua-types' */ export interface JsonMockRender { /** The component tree to render */ - component: LuaUIComponent + component: PackageComponent /** Optional description shown in Storybook */ description?: string } @@ -23,10 +24,10 @@ export interface JsonMockRender { */ export interface JsonMockPackage { /** Package metadata */ - metadata: LuaPackageMetadata - /** + metadata: PackageMetadata + /** * Render definitions keyed by script name - * e.g., "init.lua", "layout.lua", "render_users" + * e.g., "init", "layout", "renderUsers" */ renders: Record } @@ -52,12 +53,11 @@ export interface TemplateVariables { * Replaces {{variable}} with actual values from context */ export function processTemplates( - component: LuaUIComponent, + component: PackageComponent, variables: TemplateVariables -): LuaUIComponent { +): PackageComponent { const processValue = (value: unknown): unknown => { if (typeof value === 'string') { - // Replace {{variable}} patterns return value.replace(/\{\{([^}]+)\}\}/g, (_, key) => { const keys = key.trim().split('.') let result: unknown = variables @@ -84,5 +84,5 @@ export function processTemplates( return value } - return processValue(component) as LuaUIComponent + return processValue(component) as PackageComponent } diff --git a/storybook/src/stories/Components.stories.tsx b/storybook/src/stories/Components.stories.tsx index 480039014..92192536c 100644 --- a/storybook/src/stories/Components.stories.tsx +++ b/storybook/src/stories/Components.stories.tsx @@ -4,7 +4,7 @@ import * as Components from '../components/registry' /** * Component Registry showcases all available components - * that can be used in Lua packages. + * that can be used in MetaBuilder packages. */ const meta: Meta = { title: 'Components/Registry', diff --git a/storybook/src/stories/Introduction.mdx b/storybook/src/stories/Introduction.mdx index 847475ad8..1a84eabf5 100644 --- a/storybook/src/stories/Introduction.mdx +++ b/storybook/src/stories/Introduction.mdx @@ -2,30 +2,30 @@ import { Meta } from '@storybook/blocks' -# MetaBuilder Lua Package Storybook - -This Storybook renders **Lua packages** from the MetaBuilder platform without running the actual application. +# MetaBuilder Package Storybook + +This Storybook renders **MetaBuilder packages backed by JSON scripts** from the MetaBuilder platform without running the actual application. ## Quick Start 1. **Explorer** - Use the Auto-Discovered Packages → Explorer to browse all packages interactively 2. **Component Registry** - See all available components in Components → Registry -3. **Manual Stories** - Pre-configured stories in Lua Packages → Renderer +3. **Manual Stories** - Pre-configured stories in JSON package renders ## Auto-Discovery The storybook automatically discovers packages using `storybook.config.json`: ```json -{ - "discovery": { - "enabled": true, - "includedCategories": ["ui", "admin", "gaming", "social", "editors"], - "excludedPackages": ["shared", "lua_test"], - "minLevel": 1, - "maxLevel": 6 - } -} + { + "discovery": { + "enabled": true, + "includedCategories": ["ui", "admin", "gaming", "social", "editors"], + "excludedPackages": ["shared", "testing"], + "minLevel": 1, + "maxLevel": 6 + } + } ``` ### Context Variants @@ -37,43 +37,47 @@ Test packages with different user contexts: - **Admin (Nerd Mode)** - Level 4 with nerdMode enabled - **Supergod** - Level 6 user -## How It Works +## How It Works + +1. **JSON script packages** in `/packages/*/seed/scripts/functions.json` define UI component trees +2. **Mock data** mirrors the output structure produced by the JSON scripts +3. **PackageRenderer** (still the runtime entry) converts the component tree to React components +4. **Component Registry** maps package-defined type names to React implementations -1. **Lua packages** in `/packages/*/seed/scripts/` define UI as component trees -2. **Mock data** mirrors the output structure of Lua render functions -3. **LuaPackageRenderer** converts the component tree to React components -4. **Component Registry** maps Lua type names to React implementations - -## Package Structure - -Each Lua package follows this structure: +## Package Structure + +Each JSON script package follows this structure: ``` packages/ └── {package_name}/ - └── seed/ - ├── metadata.json # Package info - ├── components.json # Component definitions - └── scripts/ - ├── manifest.json # Script manifest - ├── init.lua # Initialization - └── *.lua # Render functions + └── seed/ + ├── metadata.json # Package info + ├── components.json # Component definitions + └── scripts/ + └── functions.json # JSON script definitions ``` -## Lua Render Output - -Lua render functions return component trees like: - -```lua -return { - type = "Card", - props = { className = "p-4" }, - children = { - { type = "Typography", props = { variant = "h5", text = "Title" } }, - { type = "Button", props = { children = "Click Me" } } - } -} -``` +## JSON Script Output + +JSON script functions return component trees like: + +```json +{ + "type": "Card", + "props": { "className": "p-4" }, + "children": [ + { + "type": "Typography", + "props": { "variant": "h5", "text": "Title" } + }, + { + "type": "Button", + "props": { "children": "Click Me" } + } + ] +} +``` ## Adding New Package Mocks @@ -85,7 +89,7 @@ return { ## Available Component Types -The component registry maps these Lua types to React: +The component registry maps these package types to React: ### Layout - `Box`, `Stack`, `Flex`, `Grid`, `Container` diff --git a/storybook/src/stories/UIHome.stories.tsx b/storybook/src/stories/UIHome.stories.tsx index a02e95c53..28d9f2bfb 100644 --- a/storybook/src/stories/UIHome.stories.tsx +++ b/storybook/src/stories/UIHome.stories.tsx @@ -35,7 +35,7 @@ const HeroSection: React.FC = () => (
Welcome to MetaBuilder - Build dynamic applications with abstract styling systems, Lua scripting, and component composition + Build dynamic applications with abstract styling systems, automation scripting, and component composition
) diff --git a/storybook/src/stories/UILevel4.stories.tsx b/storybook/src/stories/UILevel4.stories.tsx index 29b77aa7d..dce8fac16 100644 --- a/storybook/src/stories/UILevel4.stories.tsx +++ b/storybook/src/stories/UILevel4.stories.tsx @@ -63,7 +63,7 @@ const ConfigSummary: React.FC<{ {nodes}
- Lua Scripts: + Scripts: {scripts}
@@ -382,7 +382,7 @@ const BuilderWorkspace: React.FC = () => ( Application Builder

- Design your application declaratively. Define schemas, create workflows, and write Lua scripts. + Design your application declaratively. Define schemas, create workflows, and write scripts.

@@ -435,7 +435,7 @@ const BuilderWorkspace: React.FC = () => ( gap: '0.5rem' }} > - 💻 Lua Scripts + 💻 Scripts
@@ -552,7 +552,7 @@ export const TabsDemo: Story = { gap: '0.5rem' }} > - 💻 Lua Scripts + 💻 Scripts diff --git a/storybook/src/utils/packageDiscovery.ts b/storybook/src/utils/packageDiscovery.ts index da1971a9b..53460f316 100644 --- a/storybook/src/utils/packageDiscovery.ts +++ b/storybook/src/utils/packageDiscovery.ts @@ -188,7 +188,7 @@ function getKnownPackageIds(): string[] { 'github_tools', 'irc_webchat', 'json_script_example', - 'lua_test', + 'testing', 'media_center', 'nav_menu', 'notification_center', diff --git a/storybook/storybook-config.schema.json b/storybook/storybook-config.schema.json index 7180d04f8..6b1557230 100644 --- a/storybook/storybook-config.schema.json +++ b/storybook/storybook-config.schema.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Storybook Config", - "description": "Configuration for auto-discovering and rendering Lua packages in Storybook", + "description": "Configuration for auto-discovering and rendering MetaBuilder packages in Storybook", "type": "object", "properties": { "$schema": { "type": "string" }, diff --git a/storybook/storybook.config.json b/storybook/storybook.config.json index 8f314fe85..56d88752f 100644 --- a/storybook/storybook.config.json +++ b/storybook/storybook.config.json @@ -1,6 +1,6 @@ { "$schema": "./storybook-config.schema.json", - "description": "Auto-discovery configuration for Lua package Storybook", + "description": "Auto-discovery configuration for the MetaBuilder package Storybook", "packagesPath": "../packages", "packagesIndex": "../packages/index.json", @@ -8,7 +8,7 @@ "enabled": true, "scanManifests": true, "includedCategories": ["ui", "admin", "gaming", "social", "editors", "examples"], - "excludedPackages": ["shared", "lua_test"], + "excludedPackages": ["shared", "testing"], "minLevel": 0, "maxLevel": 6 },