From 9507c39f09698129f95bbc081525dbbfb23de132 Mon Sep 17 00:00:00 2001 From: JohnDoe6345789 Date: Tue, 30 Dec 2025 00:55:05 +0000 Subject: [PATCH] fix(types): enhance type safety across various modules and functions --- .../src/adapters/prisma/operations/utils.ts | 17 ++++++++++++++-- dbal/development/src/adapters/prisma/types.ts | 12 +++++++++-- .../src/blob/providers/filesystem/context.ts | 5 +++-- .../filesystem/operations/downloads.ts | 17 +++++++++------- .../filesystem/operations/listing.ts | 5 +++-- .../filesystem/operations/maintenance.ts | 14 +++++++------ .../filesystem/operations/metadata.ts | 7 ++++--- .../filesystem/operations/uploads.ts | 15 ++++++++------ .../src/blob/providers/s3/client.ts | 8 +++++++- .../blob/providers/s3/operations/downloads.ts | 18 +++++++++-------- .../blob/providers/s3/operations/listing.ts | 5 +++-- .../providers/s3/operations/maintenance.ts | 12 ++++++----- .../blob/providers/s3/operations/metadata.ts | 12 ++++++----- .../blob/providers/s3/operations/uploads.ts | 12 ++++++----- dbal/development/src/core/kv/index.ts | 6 +++--- .../src/core/kv/operations/write.ts | 4 ++-- dbal/development/src/core/kv/scoping.ts | 2 +- dbal/development/src/core/kv/types.ts | 8 ++++---- .../tools/cpp-build-assistant/workflow.ts | 5 +++-- .../src/lib/db/dbal-client/utils/get-model.ts | 12 +++++++++-- .../functions/create-tenant.ts | 8 +++++++- .../src/lib/lua/ui/load-lua-ui-package.ts | 10 ++++++---- .../src/lib/packages/core/package-types.ts | 20 ++++++++++--------- .../loader/load-package-index.test.ts | 4 ++-- .../package-glue/loader/load-package-index.ts | 2 +- .../scripts/get-package-components.ts | 6 ++++-- .../scripts/get-package-examples.ts | 6 ++++-- frontends/nextjs/src/types/utility-types.d.ts | 8 ++++---- 28 files changed, 165 insertions(+), 95 deletions(-) diff --git a/dbal/development/src/adapters/prisma/operations/utils.ts b/dbal/development/src/adapters/prisma/operations/utils.ts index e2eac8648..a1fbc3959 100644 --- a/dbal/development/src/adapters/prisma/operations/utils.ts +++ b/dbal/development/src/adapters/prisma/operations/utils.ts @@ -1,9 +1,22 @@ import type { PrismaContext } from '../types' import { DBALError } from '../../core/foundation/errors' -export function getModel(context: PrismaContext, entity: string): any { +type PrismaModelDelegate = { + findMany: (...args: unknown[]) => Promise + findUnique: (...args: unknown[]) => Promise + findFirst: (...args: unknown[]) => Promise + create: (...args: unknown[]) => Promise + createMany: (...args: unknown[]) => Promise<{ count: number }> + update: (...args: unknown[]) => Promise + updateMany: (...args: unknown[]) => Promise<{ count: number }> + delete: (...args: unknown[]) => Promise + deleteMany: (...args: unknown[]) => Promise<{ count: number }> + upsert: (...args: unknown[]) => Promise +} + +export function getModel(context: PrismaContext, entity: string): PrismaModelDelegate { const modelName = entity.charAt(0).toLowerCase() + entity.slice(1) - const model = (context.prisma as any)[modelName] + const model = (context.prisma as Record)[modelName] if (!model) { throw DBALError.notFound(`Entity ${entity} not found`) diff --git a/dbal/development/src/adapters/prisma/types.ts b/dbal/development/src/adapters/prisma/types.ts index 93cdd1483..c8b1e579f 100644 --- a/dbal/development/src/adapters/prisma/types.ts +++ b/dbal/development/src/adapters/prisma/types.ts @@ -1,4 +1,5 @@ import type { AdapterCapabilities } from '../adapter' +import type { PrismaClient } from '@prisma/client' export type PrismaAdapterDialect = 'postgres' | 'mysql' | 'sqlite' | 'generic' @@ -8,17 +9,24 @@ export interface PrismaAdapterOptions { } export interface PrismaContext { - prisma: any + prisma: PrismaClient queryTimeout: number dialect: PrismaAdapterDialect } +export interface ListOptions { + filter?: Record + sort?: Record + limit?: number + offset?: number +} + export interface PrismaOperations { create(entity: string, data: Record): Promise read(entity: string, id: string): Promise update(entity: string, id: string, data: Record): Promise delete(entity: string, id: string): Promise - list(entity: string, options?: any): Promise + list(entity: string, options?: ListOptions): Promise findFirst(entity: string, filter?: Record): Promise findByField(entity: string, field: string, value: unknown): Promise upsert( diff --git a/dbal/development/src/blob/providers/filesystem/context.ts b/dbal/development/src/blob/providers/filesystem/context.ts index 485614c5d..fa07cfcb0 100644 --- a/dbal/development/src/blob/providers/filesystem/context.ts +++ b/dbal/development/src/blob/providers/filesystem/context.ts @@ -22,7 +22,8 @@ export function createFilesystemContext(config: BlobStorageConfig): FilesystemCo async function ensureBasePath(basePath: string) { try { await fs.mkdir(basePath, { recursive: true }) - } catch (error: any) { - throw new Error(`Failed to create base path: ${error.message}`) + } catch (error) { + const fsError = error as NodeJS.ErrnoException + throw new Error(`Failed to create base path: ${fsError.message}`) } } diff --git a/dbal/development/src/blob/providers/filesystem/operations/downloads.ts b/dbal/development/src/blob/providers/filesystem/operations/downloads.ts index a342a8440..d7493d3e1 100644 --- a/dbal/development/src/blob/providers/filesystem/operations/downloads.ts +++ b/dbal/development/src/blob/providers/filesystem/operations/downloads.ts @@ -1,4 +1,5 @@ import { promises as fs, createReadStream } from 'fs' +import type { ReadStreamOptions } from 'fs' import type { DownloadOptions } from '../../../blob-storage' import { DBALError } from '../../../core/foundation/errors' import type { FilesystemContext } from '../context' @@ -26,14 +27,15 @@ export async function downloadBuffer( } return data - } catch (error: any) { - if (error.code === 'ENOENT') { + } catch (error) { + const fsError = error as NodeJS.ErrnoException + if (fsError.code === 'ENOENT') { throw DBALError.notFound(`Blob not found: ${key}`) } if (error instanceof DBALError) { throw error } - throw DBALError.internal(`Filesystem download failed: ${error.message}`) + throw DBALError.internal(`Filesystem download failed: ${fsError.message}`) } } @@ -47,7 +49,7 @@ export async function downloadStream( try { await fs.access(filePath) - const streamOptions: any = {} + const streamOptions: { start?: number; end?: number } = {} if (options.offset !== undefined) { streamOptions.start = options.offset } @@ -56,10 +58,11 @@ export async function downloadStream( } return createReadStream(filePath, streamOptions) - } catch (error: any) { - if (error.code === 'ENOENT') { + } catch (error) { + const fsError = error as NodeJS.ErrnoException + if (fsError.code === 'ENOENT') { throw DBALError.notFound(`Blob not found: ${key}`) } - throw DBALError.internal(`Filesystem download stream failed: ${error.message}`) + throw DBALError.internal(`Filesystem download stream failed: ${fsError.message}`) } } diff --git a/dbal/development/src/blob/providers/filesystem/operations/listing.ts b/dbal/development/src/blob/providers/filesystem/operations/listing.ts index 83242b147..c16432664 100644 --- a/dbal/development/src/blob/providers/filesystem/operations/listing.ts +++ b/dbal/development/src/blob/providers/filesystem/operations/listing.ts @@ -22,8 +22,9 @@ export async function listBlobs( isTruncated: items.length > maxKeys, nextToken: items.length > maxKeys ? items[maxKeys].key : undefined, } - } catch (error: any) { - throw DBALError.internal(`Filesystem list failed: ${error.message}`) + } catch (error) { + const fsError = error as Error + throw DBALError.internal(`Filesystem list failed: ${fsError.message}`) } } diff --git a/dbal/development/src/blob/providers/filesystem/operations/maintenance.ts b/dbal/development/src/blob/providers/filesystem/operations/maintenance.ts index 67a4006ad..bb6095577 100644 --- a/dbal/development/src/blob/providers/filesystem/operations/maintenance.ts +++ b/dbal/development/src/blob/providers/filesystem/operations/maintenance.ts @@ -24,11 +24,12 @@ export async function deleteBlob( } return true - } catch (error: any) { - if (error.code === 'ENOENT') { + } catch (error) { + const fsError = error as NodeJS.ErrnoException + if (fsError.code === 'ENOENT') { throw DBALError.notFound(`Blob not found: ${key}`) } - throw DBALError.internal(`Filesystem delete failed: ${error.message}`) + throw DBALError.internal(`Filesystem delete failed: ${fsError.message}`) } } @@ -56,11 +57,12 @@ export async function copyBlob( } catch { return await readMetadata(context, destKey) } - } catch (error: any) { - if (error.code === 'ENOENT') { + } catch (error) { + const fsError = error as NodeJS.ErrnoException + if (fsError.code === 'ENOENT') { throw DBALError.notFound(`Source blob not found: ${sourceKey}`) } - throw DBALError.internal(`Filesystem copy failed: ${error.message}`) + throw DBALError.internal(`Filesystem copy failed: ${fsError.message}`) } } diff --git a/dbal/development/src/blob/providers/filesystem/operations/metadata.ts b/dbal/development/src/blob/providers/filesystem/operations/metadata.ts index 9c8f464a5..3e5fbc74a 100644 --- a/dbal/development/src/blob/providers/filesystem/operations/metadata.ts +++ b/dbal/development/src/blob/providers/filesystem/operations/metadata.ts @@ -28,11 +28,12 @@ export async function readMetadata( lastModified: stats.mtime, } } - } catch (error: any) { - if (error.code === 'ENOENT') { + } catch (error) { + const fsError = error as NodeJS.ErrnoException + if (fsError.code === 'ENOENT') { throw DBALError.notFound(`Blob not found: ${key}`) } - throw DBALError.internal(`Filesystem get metadata failed: ${error.message}`) + throw DBALError.internal(`Filesystem get metadata failed: ${fsError.message}`) } } diff --git a/dbal/development/src/blob/providers/filesystem/operations/uploads.ts b/dbal/development/src/blob/providers/filesystem/operations/uploads.ts index b4d3eff90..b357b14ce 100644 --- a/dbal/development/src/blob/providers/filesystem/operations/uploads.ts +++ b/dbal/development/src/blob/providers/filesystem/operations/uploads.ts @@ -17,8 +17,9 @@ async function ensureWritableDestination( try { await fs.access(filePath) throw DBALError.conflict(`Blob already exists: ${filePath}`) - } catch (error: any) { - if (error.code !== 'ENOENT') { + } catch (error) { + const fsError = error as NodeJS.ErrnoException + if (fsError.code !== 'ENOENT') { throw error } } @@ -52,11 +53,12 @@ export async function uploadBuffer( await fs.writeFile(metaPath, JSON.stringify(metadata, null, 2)) return metadata - } catch (error: any) { + } catch (error) { if (error instanceof DBALError) { throw error } - throw DBALError.internal(`Filesystem upload failed: ${error.message}`) + const fsError = error as Error + throw DBALError.internal(`Filesystem upload failed: ${fsError.message}`) } } @@ -100,10 +102,11 @@ export async function uploadStream( await writeMetadata(context, key, metadata) return metadata - } catch (error: any) { + } catch (error) { if (error instanceof DBALError) { throw error } - throw DBALError.internal(`Filesystem stream upload failed: ${error.message}`) + const fsError = error as Error + throw DBALError.internal(`Filesystem stream upload failed: ${fsError.message}`) } } diff --git a/dbal/development/src/blob/providers/s3/client.ts b/dbal/development/src/blob/providers/s3/client.ts index ad4735383..acbe4b78b 100644 --- a/dbal/development/src/blob/providers/s3/client.ts +++ b/dbal/development/src/blob/providers/s3/client.ts @@ -1,8 +1,14 @@ import type { BlobStorageConfig } from '../../blob-storage' +/** S3Client type from @aws-sdk/client-s3 - using interface to avoid requiring the package */ +interface S3ClientLike { + send(command: unknown): Promise + destroy(): void +} + export interface S3Context { bucket: string - s3Client: any + s3Client: S3ClientLike } export async function createS3Context(config: BlobStorageConfig): Promise { diff --git a/dbal/development/src/blob/providers/s3/operations/downloads.ts b/dbal/development/src/blob/providers/s3/operations/downloads.ts index 90b020958..acf5ef43c 100644 --- a/dbal/development/src/blob/providers/s3/operations/downloads.ts +++ b/dbal/development/src/blob/providers/s3/operations/downloads.ts @@ -25,11 +25,12 @@ export async function downloadBuffer( } return Buffer.concat(chunks) - } catch (error: any) { - if (error.name === 'NoSuchKey') { + } catch (error) { + const s3Error = error as { name?: string; message?: string } + if (s3Error.name === 'NoSuchKey') { throw DBALError.notFound(`Blob not found: ${key}`) } - throw DBALError.internal(`S3 download failed: ${error.message}`) + throw DBALError.internal(`S3 download failed: ${s3Error.message}`) } } @@ -47,12 +48,13 @@ export async function downloadStream( Range: buildRangeHeader(options), }) - const response = await context.s3Client.send(command) - return response.Body as any - } catch (error: any) { - if (error.name === 'NoSuchKey') { + const response = await context.s3Client.send(command) as { Body: ReadableStream | NodeJS.ReadableStream } + return response.Body + } catch (error) { + const s3Error = error as { name?: string; message?: string } + if (s3Error.name === 'NoSuchKey') { throw DBALError.notFound(`Blob not found: ${key}`) } - throw DBALError.internal(`S3 download stream failed: ${error.message}`) + throw DBALError.internal(`S3 download stream failed: ${s3Error.message}`) } } diff --git a/dbal/development/src/blob/providers/s3/operations/listing.ts b/dbal/development/src/blob/providers/s3/operations/listing.ts index 859a2c9fd..2279d08c3 100644 --- a/dbal/development/src/blob/providers/s3/operations/listing.ts +++ b/dbal/development/src/blob/providers/s3/operations/listing.ts @@ -31,8 +31,9 @@ export async function listBlobs( nextToken: response.NextContinuationToken, isTruncated: response.IsTruncated || false, } - } catch (error: any) { - throw DBALError.internal(`S3 list failed: ${error.message}`) + } catch (error) { + const s3Error = error as Error + throw DBALError.internal(`S3 list failed: ${s3Error.message}`) } } diff --git a/dbal/development/src/blob/providers/s3/operations/maintenance.ts b/dbal/development/src/blob/providers/s3/operations/maintenance.ts index cc4dadb08..d46c55260 100644 --- a/dbal/development/src/blob/providers/s3/operations/maintenance.ts +++ b/dbal/development/src/blob/providers/s3/operations/maintenance.ts @@ -17,8 +17,9 @@ export async function deleteObject( await context.s3Client.send(command) return true - } catch (error: any) { - throw DBALError.internal(`S3 delete failed: ${error.message}`) + } catch (error: unknown) { + const s3Error = error as { message?: string } + throw DBALError.internal(`S3 delete failed: ${s3Error.message || 'Unknown error'}`) } } @@ -39,10 +40,11 @@ export async function copyObject( await context.s3Client.send(command) return await getMetadata(context, destKey) - } catch (error: any) { - if (error.name === 'NoSuchKey') { + } catch (error: unknown) { + const s3Error = error as { name?: string; message?: string } + if (s3Error.name === 'NoSuchKey') { throw DBALError.notFound(`Source blob not found: ${sourceKey}`) } - throw DBALError.internal(`S3 copy failed: ${error.message}`) + throw DBALError.internal(`S3 copy failed: ${s3Error.message || 'Unknown error'}`) } } diff --git a/dbal/development/src/blob/providers/s3/operations/metadata.ts b/dbal/development/src/blob/providers/s3/operations/metadata.ts index 3e51c4d6c..fc78280c7 100644 --- a/dbal/development/src/blob/providers/s3/operations/metadata.ts +++ b/dbal/development/src/blob/providers/s3/operations/metadata.ts @@ -24,11 +24,12 @@ export async function getMetadata( lastModified: response.LastModified || new Date(), customMetadata: response.Metadata, } - } catch (error: any) { - if (error.name === 'NotFound') { + } catch (error: unknown) { + const s3Error = error as { name?: string; message?: string } + if (s3Error.name === 'NotFound') { throw DBALError.notFound(`Blob not found: ${key}`) } - throw DBALError.internal(`S3 head object failed: ${error.message}`) + throw DBALError.internal(`S3 head object failed: ${s3Error.message || 'Unknown error'}`) } } @@ -49,7 +50,8 @@ export async function generatePresignedUrl( return await getSignedUrl(context.s3Client, command, { expiresIn: expirationSeconds, }) - } catch (error: any) { - throw DBALError.internal(`S3 presigned URL generation failed: ${error.message}`) + } catch (error: unknown) { + const s3Error = error as { message?: string } + throw DBALError.internal(`S3 presigned URL generation failed: ${s3Error.message || 'Unknown error'}`) } } diff --git a/dbal/development/src/blob/providers/s3/operations/uploads.ts b/dbal/development/src/blob/providers/s3/operations/uploads.ts index 0de20293a..097280f64 100644 --- a/dbal/development/src/blob/providers/s3/operations/uploads.ts +++ b/dbal/development/src/blob/providers/s3/operations/uploads.ts @@ -29,11 +29,12 @@ export async function uploadBuffer( lastModified: new Date(), customMetadata: options.metadata, } - } catch (error: any) { - if (error.name === 'NoSuchBucket') { + } catch (error: unknown) { + const s3Error = error as { name?: string; message?: string } + if (s3Error.name === 'NoSuchBucket') { throw DBALError.notFound(`Bucket not found: ${context.bucket}`) } - throw DBALError.internal(`S3 upload failed: ${error.message}`) + throw DBALError.internal(`S3 upload failed: ${s3Error.message || 'Unknown error'}`) } } @@ -68,7 +69,8 @@ export async function uploadStream( lastModified: new Date(), customMetadata: options.metadata, } - } catch (error: any) { - throw DBALError.internal(`S3 stream upload failed: ${error.message}`) + } catch (error: unknown) { + const s3Error = error as { message?: string } + throw DBALError.internal(`S3 stream upload failed: ${s3Error.message || 'Unknown error'}`) } } diff --git a/dbal/development/src/core/kv/index.ts b/dbal/development/src/core/kv/index.ts index 4d5814f7b..de58cc812 100644 --- a/dbal/development/src/core/kv/index.ts +++ b/dbal/development/src/core/kv/index.ts @@ -23,15 +23,15 @@ export class InMemoryKVStore implements KVStore { return exists(this.state, key, context) } - listAdd(key: string, items: any[], context: TenantContext): Promise { + listAdd(key: string, items: StorableValue[], context: TenantContext): Promise { return listAdd(this.state, key, items, context) } - listGet(key: string, context: TenantContext, start?: number, end?: number): Promise { + listGet(key: string, context: TenantContext, start?: number, end?: number): Promise { return listGet(this.state, key, context, start, end) } - listRemove(key: string, value: any, context: TenantContext): Promise { + listRemove(key: string, value: StorableValue, context: TenantContext): Promise { return listRemove(this.state, key, value, context) } diff --git a/dbal/development/src/core/kv/operations/write.ts b/dbal/development/src/core/kv/operations/write.ts index cc7b8bed2..d46bf5fa2 100644 --- a/dbal/development/src/core/kv/operations/write.ts +++ b/dbal/development/src/core/kv/operations/write.ts @@ -73,7 +73,7 @@ export async function deleteValue( export async function listAdd( state: KVStoreState, key: string, - items: any[], + items: StorableValue[], context: TenantContext ): Promise { if (!context.canWrite('kv')) { @@ -95,7 +95,7 @@ export async function listAdd( export async function listRemove( state: KVStoreState, key: string, - valueToRemove: any, + valueToRemove: StorableValue, context: TenantContext ): Promise { if (!context.canWrite('kv')) { diff --git a/dbal/development/src/core/kv/scoping.ts b/dbal/development/src/core/kv/scoping.ts index 95109e63c..456d5436a 100644 --- a/dbal/development/src/core/kv/scoping.ts +++ b/dbal/development/src/core/kv/scoping.ts @@ -23,7 +23,7 @@ export function isExpired(entry: KVStoreEntry): boolean { return Boolean(entry.expiresAt && entry.expiresAt < new Date()) } -export function deepEquals(a: any, b: any): boolean { +export function deepEquals(a: StorableValue, b: StorableValue): boolean { return JSON.stringify(a) === JSON.stringify(b) } diff --git a/dbal/development/src/core/kv/types.ts b/dbal/development/src/core/kv/types.ts index e94e5c72e..86c22bb3a 100644 --- a/dbal/development/src/core/kv/types.ts +++ b/dbal/development/src/core/kv/types.ts @@ -1,6 +1,6 @@ import { TenantContext } from '../foundation/tenant-context' -export type StorableValue = string | number | boolean | null | object | Array +export type StorableValue = string | number | boolean | null | object | StorableValue[] export interface KVStoreEntry { key: string @@ -29,9 +29,9 @@ export interface KVStore { set(key: string, value: StorableValue, context: TenantContext, ttl?: number): Promise delete(key: string, context: TenantContext): Promise exists(key: string, context: TenantContext): Promise - listAdd(key: string, items: any[], context: TenantContext): Promise - listGet(key: string, context: TenantContext, start?: number, end?: number): Promise - listRemove(key: string, value: any, context: TenantContext): Promise + listAdd(key: string, items: StorableValue[], context: TenantContext): Promise + listGet(key: string, context: TenantContext, start?: number, end?: number): Promise + listRemove(key: string, value: StorableValue, context: TenantContext): Promise listLength(key: string, context: TenantContext): Promise listClear(key: string, context: TenantContext): Promise mget(keys: string[], context: TenantContext): Promise> diff --git a/dbal/shared/tools/cpp-build-assistant/workflow.ts b/dbal/shared/tools/cpp-build-assistant/workflow.ts index e18ee8f39..f38283f03 100644 --- a/dbal/shared/tools/cpp-build-assistant/workflow.ts +++ b/dbal/shared/tools/cpp-build-assistant/workflow.ts @@ -13,8 +13,9 @@ export const execCommand = (command: string, cppDir: string, options: ExecOption stdio: options.silent ? 'pipe' : 'inherit', }) return { success: true, output: result as string } - } catch (error: any) { - return { success: false, error: error.message, output: error.stdout } + } catch (error: unknown) { + const execError = error as { message?: string; stdout?: string } + return { success: false, error: execError.message, output: execError.stdout } } } diff --git a/frontends/nextjs/src/lib/db/dbal-client/utils/get-model.ts b/frontends/nextjs/src/lib/db/dbal-client/utils/get-model.ts index 574b3cb87..b3eeacee0 100644 --- a/frontends/nextjs/src/lib/db/dbal-client/utils/get-model.ts +++ b/frontends/nextjs/src/lib/db/dbal-client/utils/get-model.ts @@ -1,11 +1,19 @@ import { prisma } from '../../../config/prisma' +type PrismaModel = { + findMany: (...args: unknown[]) => Promise + findUnique: (...args: unknown[]) => Promise + create: (...args: unknown[]) => Promise + update: (...args: unknown[]) => Promise + delete: (...args: unknown[]) => Promise +} + /** * Get the Prisma model by entity name */ -export function getModel(entity: string): any { +export function getModel(entity: string): PrismaModel { const modelName = entity.charAt(0).toLowerCase() + entity.slice(1) - const model = (prisma as any)[modelName] + const model = (prisma as Record)[modelName] if (!model) { throw new Error(`Entity ${entity} not found in Prisma schema`) } diff --git a/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/create-tenant.ts b/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/create-tenant.ts index b479761f5..e8d510c37 100644 --- a/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/create-tenant.ts +++ b/frontends/nextjs/src/lib/dbal/core/client/dbal-integration/functions/create-tenant.ts @@ -1,5 +1,11 @@ import { DBALClient, type DBALConfig } from '@/dbal' -export async function createTenant(id: string, limits?: any): Promise { +interface TenantLimits { + maxStorage?: number + maxUsers?: number + maxApiCalls?: number +} + +export async function createTenant(id: string, limits?: TenantLimits): Promise { this.tenants.set(id, { limits: limits || {} }) } diff --git a/frontends/nextjs/src/lib/lua/ui/load-lua-ui-package.ts b/frontends/nextjs/src/lib/lua/ui/load-lua-ui-package.ts index 03c1ea9c1..cfdb1e6a3 100644 --- a/frontends/nextjs/src/lib/lua/ui/load-lua-ui-package.ts +++ b/frontends/nextjs/src/lib/lua/ui/load-lua-ui-package.ts @@ -6,6 +6,8 @@ import { createLuaEngine } from '@/lib/lua/engine/core/create-lua-engine' import { fromLua } from '@/lib/lua/functions/converters/from-lua' import { pushToLua } from '@/lib/lua/functions/converters/push-to-lua' +import type { JsonValue } from '@/types/utility-types' + import { normalizeLuaComponent } from './normalize-lua-structure' import type { LuaUIManifest, LuaUIPackage, LuaUIPage } from './types/lua-ui-package' @@ -87,7 +89,7 @@ export async function loadLuaUIPackage(packagePath: string): Promise any> = {} + const actions: Record JsonValue> = {} if (manifest.actions) { for (const actionManifest of manifest.actions) { const actionPath = join(packagePath, actionManifest.file) @@ -150,8 +152,8 @@ export async function loadLuaUIPackage(packagePath: string): Promise any { - return (...args: any[]) => { +function createLuaFunctionWrapper(luaSource: string, functionName: string): (...args: JsonValue[]) => JsonValue { + return (...args: JsonValue[]) => { // Create a new Lua engine for this call const engine = createLuaEngine() const L = engine.L @@ -190,7 +192,7 @@ function createLuaFunctionWrapper(luaSource: string, functionName: string): (... } // Get the result - const result = fromLua(L, -1) + const result = fromLua(L, -1) as JsonValue engine.destroy() return result diff --git a/frontends/nextjs/src/lib/packages/core/package-types.ts b/frontends/nextjs/src/lib/packages/core/package-types.ts index f1803d3f8..744346b22 100644 --- a/frontends/nextjs/src/lib/packages/core/package-types.ts +++ b/frontends/nextjs/src/lib/packages/core/package-types.ts @@ -1,3 +1,5 @@ +import type { JsonObject, JsonValue } from '@/types/utility-types' + export interface PackageManifest { id: string name: string @@ -24,18 +26,18 @@ export interface PackageManifest { } export interface PackageContent { - schemas: unknown[] - pages: unknown[] - workflows: unknown[] - luaScripts: unknown[] - componentHierarchy: Record - componentConfigs: Record - cssClasses?: unknown[] - dropdownConfigs?: unknown[] + schemas: JsonValue[] + pages: JsonValue[] + workflows: JsonValue[] + luaScripts: JsonValue[] + componentHierarchy: JsonObject + componentConfigs: JsonObject + cssClasses?: JsonValue[] + dropdownConfigs?: JsonValue[] seedData?: PackageSeedData } -export type PackageSeedRecord = Record +export type PackageSeedRecord = JsonObject export type PackageSeedData = Record diff --git a/frontends/nextjs/src/lib/packages/package-glue/loader/load-package-index.test.ts b/frontends/nextjs/src/lib/packages/package-glue/loader/load-package-index.test.ts index 77cd02d3e..433f7127d 100644 --- a/frontends/nextjs/src/lib/packages/package-glue/loader/load-package-index.test.ts +++ b/frontends/nextjs/src/lib/packages/package-glue/loader/load-package-index.test.ts @@ -4,12 +4,12 @@ import { loadPackageIndex } from './load-package-index' const originalFetch = global.fetch -const mockFetch = vi.fn() +const mockFetch = vi.fn() describe('loadPackageIndex', () => { beforeEach(() => { mockFetch.mockReset() - global.fetch = mockFetch as unknown as typeof fetch + global.fetch = mockFetch }) afterEach(() => { diff --git a/frontends/nextjs/src/lib/packages/package-glue/loader/load-package-index.ts b/frontends/nextjs/src/lib/packages/package-glue/loader/load-package-index.ts index e3bbb2723..eac9a4271 100644 --- a/frontends/nextjs/src/lib/packages/package-glue/loader/load-package-index.ts +++ b/frontends/nextjs/src/lib/packages/package-glue/loader/load-package-index.ts @@ -6,7 +6,7 @@ export interface PackageIndexEntry { author?: string category?: string dependencies?: string[] - exports?: { components?: unknown[] } + exports?: { components?: string[] } } interface PackageIndexResponse { diff --git a/frontends/nextjs/src/lib/packages/package-glue/scripts/get-package-components.ts b/frontends/nextjs/src/lib/packages/package-glue/scripts/get-package-components.ts index f0b322644..53fbfe737 100644 --- a/frontends/nextjs/src/lib/packages/package-glue/scripts/get-package-components.ts +++ b/frontends/nextjs/src/lib/packages/package-glue/scripts/get-package-components.ts @@ -1,3 +1,5 @@ -export function getPackageComponents(packageId: string): unknown[] { - return [] +import type { PackageComponent, PackageDefinition } from '../types' + +export function getPackageComponents(pkg: PackageDefinition): PackageComponent[] { + return pkg.components ?? [] } diff --git a/frontends/nextjs/src/lib/packages/package-glue/scripts/get-package-examples.ts b/frontends/nextjs/src/lib/packages/package-glue/scripts/get-package-examples.ts index 5b03a9763..a48388258 100644 --- a/frontends/nextjs/src/lib/packages/package-glue/scripts/get-package-examples.ts +++ b/frontends/nextjs/src/lib/packages/package-glue/scripts/get-package-examples.ts @@ -1,3 +1,5 @@ -export function getPackageExamples(packageId: string): unknown[] { - return [] +import type { PackageDefinition, PackageExamples } from '../types' + +export function getPackageExamples(pkg: PackageDefinition): PackageExamples { + return pkg.examples ?? {} } diff --git a/frontends/nextjs/src/types/utility-types.d.ts b/frontends/nextjs/src/types/utility-types.d.ts index bc1d3fddb..6a13fc221 100644 --- a/frontends/nextjs/src/types/utility-types.d.ts +++ b/frontends/nextjs/src/types/utility-types.d.ts @@ -1,12 +1,12 @@ /** - * Utility types for type-safe replacements of `any` + * Utility types for safer, flexible replacements * - * Use these types instead of `any` for better type safety. + * Use these types for better type safety. */ /** - * Represents any valid JSON value - * Use this instead of `any` for JSON data + * Represents a valid JSON value + * Use this for JSON data */ export type JsonValue = | string