mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-26 14:54:55 +00:00
code: nextjs,lua,frontends (3 files)
This commit is contained in:
125
dbal/ts/tests/core/client-lua-scripts.test.ts
Normal file
125
dbal/ts/tests/core/client-lua-scripts.test.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { DBALClient } from '../../src/core/client'
|
||||
import { DBALError, DBALErrorCode } from '../../src/core/errors'
|
||||
|
||||
const mockAdapter = vi.hoisted(() => ({
|
||||
create: vi.fn(),
|
||||
read: vi.fn(),
|
||||
update: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
list: vi.fn(),
|
||||
findFirst: vi.fn(),
|
||||
findByField: vi.fn(),
|
||||
upsert: vi.fn(),
|
||||
updateByField: vi.fn(),
|
||||
deleteByField: vi.fn(),
|
||||
deleteMany: vi.fn(),
|
||||
createMany: vi.fn(),
|
||||
updateMany: vi.fn(),
|
||||
getCapabilities: vi.fn(),
|
||||
close: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('../../src/adapters/prisma-adapter', () => ({
|
||||
PrismaAdapter: vi.fn(() => mockAdapter),
|
||||
}))
|
||||
|
||||
const baseConfig = {
|
||||
mode: 'development' as const,
|
||||
adapter: 'prisma' as const,
|
||||
database: { url: 'file:memory' },
|
||||
}
|
||||
|
||||
const luaScriptInput = {
|
||||
name: 'health_check',
|
||||
description: 'Simple health check',
|
||||
code: 'return true',
|
||||
isSandboxed: true,
|
||||
allowedGlobals: ['math'],
|
||||
timeoutMs: 1000,
|
||||
createdBy: '11111111-1111-1111-1111-111111111111',
|
||||
}
|
||||
|
||||
const luaScriptRecord = {
|
||||
...luaScriptInput,
|
||||
id: '22222222-2222-2222-2222-222222222222',
|
||||
createdAt: new Date('2024-01-01T00:00:00.000Z'),
|
||||
updatedAt: new Date('2024-01-02T00:00:00.000Z'),
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
Object.values(mockAdapter).forEach(value => {
|
||||
if (typeof value === 'function' && 'mockReset' in value) {
|
||||
value.mockReset()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('DBALClient luaScripts', () => {
|
||||
it('creates lua scripts via adapter', async () => {
|
||||
mockAdapter.create.mockResolvedValue(luaScriptRecord)
|
||||
|
||||
const client = new DBALClient(baseConfig)
|
||||
const result = await client.luaScripts.create(luaScriptInput)
|
||||
|
||||
expect(mockAdapter.create).toHaveBeenCalledWith('LuaScript', luaScriptInput)
|
||||
expect(result).toEqual(luaScriptRecord)
|
||||
})
|
||||
|
||||
it('rejects invalid lua script data before adapter call', async () => {
|
||||
const client = new DBALClient(baseConfig)
|
||||
|
||||
await expect(client.luaScripts.create({
|
||||
...luaScriptInput,
|
||||
name: '',
|
||||
})).rejects.toMatchObject({ code: DBALErrorCode.VALIDATION_ERROR })
|
||||
|
||||
expect(mockAdapter.create).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('maps lua script create conflicts to friendly message', async () => {
|
||||
mockAdapter.create.mockRejectedValue(DBALError.conflict('unique violation'))
|
||||
|
||||
const client = new DBALClient(baseConfig)
|
||||
|
||||
await expect(client.luaScripts.create(luaScriptInput)).rejects.toMatchObject({
|
||||
code: DBALErrorCode.CONFLICT,
|
||||
message: "Lua script with name 'health_check' already exists",
|
||||
})
|
||||
})
|
||||
|
||||
it('throws not found when reading missing lua scripts', async () => {
|
||||
mockAdapter.read.mockResolvedValue(null)
|
||||
|
||||
const client = new DBALClient(baseConfig)
|
||||
|
||||
await expect(client.luaScripts.read(luaScriptRecord.id)).rejects.toMatchObject({
|
||||
code: DBALErrorCode.NOT_FOUND,
|
||||
})
|
||||
})
|
||||
|
||||
it('updates, deletes, and lists lua scripts', async () => {
|
||||
const updatedRecord = { ...luaScriptRecord, timeoutMs: 2000 }
|
||||
mockAdapter.update.mockResolvedValue(updatedRecord)
|
||||
mockAdapter.delete.mockResolvedValue(true)
|
||||
mockAdapter.list.mockResolvedValue({
|
||||
data: [luaScriptRecord],
|
||||
total: 1,
|
||||
page: 1,
|
||||
limit: 20,
|
||||
hasMore: false,
|
||||
})
|
||||
|
||||
const client = new DBALClient(baseConfig)
|
||||
|
||||
const updateResult = await client.luaScripts.update(luaScriptRecord.id, { timeoutMs: 2000 })
|
||||
expect(updateResult).toEqual(updatedRecord)
|
||||
|
||||
const deleteResult = await client.luaScripts.delete(luaScriptRecord.id)
|
||||
expect(deleteResult).toBe(true)
|
||||
|
||||
const listResult = await client.luaScripts.list()
|
||||
expect(listResult.data).toEqual([luaScriptRecord])
|
||||
expect(mockAdapter.list).toHaveBeenCalledWith('LuaScript', undefined)
|
||||
})
|
||||
})
|
||||
16
frontends/nextjs/src/app/api/levels/route.ts
Normal file
16
frontends/nextjs/src/app/api/levels/route.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { NextResponse } from 'next/server'
|
||||
|
||||
import { PERMISSION_LEVELS } from '@/app/levels/levels-data'
|
||||
|
||||
export async function GET(request: Request) {
|
||||
const url = new URL(request.url)
|
||||
const rawLevel = url.searchParams.get('level')
|
||||
const normalized = rawLevel?.toLowerCase().trim()
|
||||
const filtered = normalized
|
||||
? PERMISSION_LEVELS.filter(
|
||||
(level) => level.key === normalized || String(level.id) === normalized
|
||||
)
|
||||
: PERMISSION_LEVELS
|
||||
|
||||
return NextResponse.json({ levels: filtered })
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import type { LuaScript } from '../types/level-types'
|
||||
import type { LuaExecutionContext, LuaExecutionResult } from './functions/types'
|
||||
import { createLuaEngine } from './create-lua-engine'
|
||||
import { createSandboxedLuaEngine } from './create-sandboxed-lua-engine'
|
||||
|
||||
type LuaScriptProfile = Pick<LuaScript, 'isSandboxed' | 'allowedGlobals' | 'timeoutMs'>
|
||||
|
||||
export async function executeLuaScriptWithProfile(
|
||||
code: string,
|
||||
context: LuaExecutionContext = {},
|
||||
profile: LuaScriptProfile = {}
|
||||
): Promise<LuaExecutionResult> {
|
||||
const isSandboxed = profile.isSandboxed ?? true
|
||||
|
||||
if (!isSandboxed) {
|
||||
const engine = createLuaEngine()
|
||||
try {
|
||||
return await engine.execute(code, context)
|
||||
} finally {
|
||||
engine.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
const engine = createSandboxedLuaEngine(profile.timeoutMs ?? 5000)
|
||||
engine.setAllowedGlobals(profile.allowedGlobals)
|
||||
|
||||
try {
|
||||
const result = await engine.executeWithSandbox(code, context)
|
||||
return result.execution
|
||||
} finally {
|
||||
engine.destroy()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user