From 53faf2e2f0d42b0040b441da2a9f2cf2dffac29d Mon Sep 17 00:00:00 2001 From: JohnDoe6345789 Date: Thu, 25 Dec 2025 14:58:58 +0000 Subject: [PATCH] fix: add .next to eslint ignores Build output directory was being linted causing false errors --- frontends/nextjs/eslint.config.js | 2 +- .../nextjs/src/lib/dbal-stub/blob/index.ts | 82 ++++++++++++++++ .../nextjs/src/lib/dbal-stub/core/kv-store.ts | 34 +++++++ .../src/lib/dbal-stub/core/tenant-context.ts | 31 ++++++ .../nextjs/src/lib/dbal-stub/core/types.ts | 11 +++ frontends/nextjs/src/lib/dbal-stub/index.ts | 94 +++++++++++++++++++ 6 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 frontends/nextjs/src/lib/dbal-stub/blob/index.ts create mode 100644 frontends/nextjs/src/lib/dbal-stub/core/kv-store.ts create mode 100644 frontends/nextjs/src/lib/dbal-stub/core/tenant-context.ts create mode 100644 frontends/nextjs/src/lib/dbal-stub/core/types.ts create mode 100644 frontends/nextjs/src/lib/dbal-stub/index.ts diff --git a/frontends/nextjs/eslint.config.js b/frontends/nextjs/eslint.config.js index d48b118e5..fe6a6ca4b 100644 --- a/frontends/nextjs/eslint.config.js +++ b/frontends/nextjs/eslint.config.js @@ -5,7 +5,7 @@ import reactRefresh from 'eslint-plugin-react-refresh' import tseslint from 'typescript-eslint' export default tseslint.config( - { ignores: ['dist', 'node_modules', 'packages/*/dist', 'packages/*/node_modules'] }, + { ignores: ['dist', 'node_modules', 'packages/*/dist', 'packages/*/node_modules', '.next/**', 'coverage/**'] }, { extends: [js.configs.recommended, ...tseslint.configs.recommended], files: ['**/*.{ts,tsx}'], diff --git a/frontends/nextjs/src/lib/dbal-stub/blob/index.ts b/frontends/nextjs/src/lib/dbal-stub/blob/index.ts new file mode 100644 index 000000000..640f9c2f8 --- /dev/null +++ b/frontends/nextjs/src/lib/dbal-stub/blob/index.ts @@ -0,0 +1,82 @@ +/** + * DBAL Blob Storage Stub + */ + +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unused-vars */ + +export interface BlobStorageConfig { + type: 'filesystem' | 'memory' | 's3' + basePath?: string +} + +export interface BlobMetadata { + contentType?: string + size?: number + lastModified?: Date + [key: string]: any +} + +export interface BlobListItem { + key: string + [key: string]: any +} + +export interface BlobListResult { + items: BlobListItem[] +} + +export interface BlobStorage { + upload(key: string, data: Buffer | string, metadata?: BlobMetadata): Promise + download(key: string): Promise + delete(key: string): Promise + exists(key: string): Promise + list(options?: { prefix?: string }): Promise + getMetadata(key: string): Promise +} + +class InMemoryBlobStorage implements BlobStorage { + private store = new Map() + + async upload(key: string, data: Buffer | string, metadata?: BlobMetadata): Promise { + const buffer = typeof data === 'string' ? Buffer.from(data) : data + this.store.set(key, { + data: buffer, + metadata: { ...metadata, size: buffer.length, lastModified: new Date() }, + }) + return key + } + + async download(key: string): Promise { + const item = this.store.get(key) + if (!item) throw new Error(`Blob not found: ${key}`) + return item.data + } + + async delete(key: string): Promise { + this.store.delete(key) + } + + async exists(key: string): Promise { + return this.store.has(key) + } + + async list(options?: { prefix?: string }): Promise { + const items: BlobListItem[] = [] + for (const key of this.store.keys()) { + if (!options?.prefix || key.startsWith(options.prefix)) { + items.push({ key }) + } + } + return { items } + } + + async getMetadata(key: string): Promise { + const item = this.store.get(key) + return item?.metadata ?? null + } +} + +export function createBlobStorage(_config: BlobStorageConfig): BlobStorage { + return new InMemoryBlobStorage() +} diff --git a/frontends/nextjs/src/lib/dbal-stub/core/kv-store.ts b/frontends/nextjs/src/lib/dbal-stub/core/kv-store.ts new file mode 100644 index 000000000..4a6fb880e --- /dev/null +++ b/frontends/nextjs/src/lib/dbal-stub/core/kv-store.ts @@ -0,0 +1,34 @@ +/** + * DBAL KV Store Stub + */ + +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unused-vars */ + +import type { TenantContext } from './tenant-context' + +export class InMemoryKVStore { + private store = new Map() + + async get(key: string, _context?: TenantContext): Promise { + return this.store.get(key) ?? null + } + + async set(key: string, value: T, _context?: TenantContext, _ttl?: number): Promise { + this.store.set(key, value) + } + + async delete(key: string, _context?: TenantContext): Promise { + return this.store.delete(key) + } + + async listAdd(key: string, items: any[], _context?: TenantContext): Promise { + const existing = this.store.get(key) || [] + this.store.set(key, [...existing, ...items]) + } + + async listGet(key: string, _context?: TenantContext, start = 0, end = -1): Promise { + const list = this.store.get(key) || [] + return end === -1 ? list.slice(start) : list.slice(start, end) + } +} diff --git a/frontends/nextjs/src/lib/dbal-stub/core/tenant-context.ts b/frontends/nextjs/src/lib/dbal-stub/core/tenant-context.ts new file mode 100644 index 000000000..c356b74d0 --- /dev/null +++ b/frontends/nextjs/src/lib/dbal-stub/core/tenant-context.ts @@ -0,0 +1,31 @@ +/** + * DBAL Tenant Context Stub + */ + +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/no-unused-vars */ + +export interface TenantContext { + tenantId: string + userId?: string +} + +export class InMemoryTenantManager { + private currentTenant: string | null = null + + setCurrentTenant(tenantId: string): void { + this.currentTenant = tenantId + } + + getCurrentTenant(): string | null { + return this.currentTenant + } + + async createTenant(_id: string, _metadata: Record, ..._args: any[]): Promise { + // Stub implementation + } + + async getTenantContext(tenantId: string, userId?: string): Promise { + return { tenantId, userId } + } +} diff --git a/frontends/nextjs/src/lib/dbal-stub/core/types.ts b/frontends/nextjs/src/lib/dbal-stub/core/types.ts new file mode 100644 index 000000000..93362d5c1 --- /dev/null +++ b/frontends/nextjs/src/lib/dbal-stub/core/types.ts @@ -0,0 +1,11 @@ +/** + * DBAL Core Types Stub + */ + +export interface User { + id: string + email: string + name?: string + level: number + tenantId: string +} diff --git a/frontends/nextjs/src/lib/dbal-stub/index.ts b/frontends/nextjs/src/lib/dbal-stub/index.ts new file mode 100644 index 000000000..f2a03896b --- /dev/null +++ b/frontends/nextjs/src/lib/dbal-stub/index.ts @@ -0,0 +1,94 @@ +/** + * DBAL Stub Module + * This provides runtime stubs for the DBAL when the full module is not available. + * Used in the frontend when DBAL is not fully configured. + */ + +/* eslint-disable @typescript-eslint/no-explicit-any */ + +export interface DBALConfig { + mode?: 'development' | 'production' + adapter?: string + auth?: any + database?: { + url?: string + } + security?: { + sandbox?: 'strict' | 'permissive' | 'disabled' + enableAuditLog?: boolean + } + [key: string]: any +} + +export interface DBALUser { + id: string + email: string + name?: string + username?: string + level?: number + role?: string + tenantId?: string + createdAt?: number | string | Date + [key: string]: any +} + +export interface ListResult { + data: T[] + total?: number +} + +export interface UsersAPI { + list(): Promise> + create(data: Partial): Promise + update(id: string, data: Partial): Promise + delete(id: string): Promise +} + +export class DBALClient { + users: UsersAPI + + constructor(_config: DBALConfig) { + // Stub users API + this.users = { + list: async () => ({ data: [], total: 0 }), + create: async (data) => ({ id: 'stub', email: data.email || '', ...data }), + update: async (id, data) => ({ id, email: '', ...data }), + delete: async () => true, + } + } + + async query(_sql: string, _params?: unknown[]): Promise { + console.warn('DBAL stub: query not implemented') + return [] + } + + async execute(_sql: string, _params?: unknown[]): Promise { + console.warn('DBAL stub: execute not implemented') + } + + async capabilities(): Promise> { + return { + users: true, + tenants: false, + kv: false, + blob: false, + } + } +} + +export class DBALError extends Error { + code: DBALErrorCode + + constructor(message: string, code: DBALErrorCode) { + super(message) + this.code = code + this.name = 'DBALError' + } +} + +export enum DBALErrorCode { + UNKNOWN = 'UNKNOWN', + CONNECTION_ERROR = 'CONNECTION_ERROR', + QUERY_ERROR = 'QUERY_ERROR', + VALIDATION_ERROR = 'VALIDATION_ERROR', +}