mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
Merge branch 'main' into dependabot/npm_and_yarn/tailwindcss-4.1.18
This commit is contained in:
@@ -35,9 +35,12 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.2",
|
||||
"@tanstack/react-query": "^5.90.16",
|
||||
"@testing-library/react": "^16.3.1",
|
||||
"@types/node": "^25.0.3",
|
||||
"@types/react": "^19.2.7",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@vitejs/plugin-react-swc": "^4.2.2",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Auth provider component (stub)
|
||||
*/
|
||||
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
export interface AuthProviderProps {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export function AuthProviderComponent({ children }: AuthProviderProps) {
|
||||
// TODO: Implement auth provider
|
||||
return children
|
||||
}
|
||||
|
||||
// Alias for compatibility
|
||||
export const AuthProvider = AuthProviderComponent
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* useAuth hook (stub)
|
||||
*/
|
||||
|
||||
export interface AuthUser {
|
||||
id: string
|
||||
username: string
|
||||
email: string
|
||||
role: string
|
||||
level: number
|
||||
}
|
||||
|
||||
export interface AuthState {
|
||||
user: AuthUser | null
|
||||
isLoading: boolean
|
||||
isAuthenticated: boolean
|
||||
}
|
||||
|
||||
export function useAuth(): AuthState {
|
||||
// TODO: Implement useAuth hook
|
||||
return {
|
||||
user: null,
|
||||
isLoading: false,
|
||||
isAuthenticated: false,
|
||||
}
|
||||
}
|
||||
12
frontends/nextjs/src/app/levels/levels-data.ts
Normal file
12
frontends/nextjs/src/app/levels/levels-data.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Levels data (stub)
|
||||
*/
|
||||
|
||||
export const levelsData = {
|
||||
public: 1,
|
||||
user: 2,
|
||||
moderator: 3,
|
||||
admin: 4,
|
||||
god: 5,
|
||||
supergod: 6,
|
||||
}
|
||||
8
frontends/nextjs/src/hooks/use-mobile.ts
Normal file
8
frontends/nextjs/src/hooks/use-mobile.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* useMobile hook (stub)
|
||||
*/
|
||||
|
||||
export function useMobile(): boolean {
|
||||
// TODO: Implement mobile detection
|
||||
return false
|
||||
}
|
||||
12
frontends/nextjs/src/hooks/useAutoRefresh.ts
Normal file
12
frontends/nextjs/src/hooks/useAutoRefresh.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* useAutoRefresh hook (stub)
|
||||
*/
|
||||
|
||||
export interface AutoRefreshOptions {
|
||||
interval?: number
|
||||
enabled?: boolean
|
||||
}
|
||||
|
||||
export function useAutoRefresh(callback: () => void, options?: AutoRefreshOptions): void {
|
||||
// TODO: Implement auto refresh
|
||||
}
|
||||
20
frontends/nextjs/src/hooks/useCodeEditor.ts
Normal file
20
frontends/nextjs/src/hooks/useCodeEditor.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* useCodeEditor hook (stub)
|
||||
*/
|
||||
|
||||
export interface EditorFile {
|
||||
path: string
|
||||
content: string
|
||||
language?: string
|
||||
}
|
||||
|
||||
export function useCodeEditor() {
|
||||
// TODO: Implement useCodeEditor
|
||||
return {
|
||||
files: [] as EditorFile[],
|
||||
currentFile: null as EditorFile | null,
|
||||
openFile: (file: EditorFile) => {},
|
||||
saveFile: (file: EditorFile) => {},
|
||||
closeFile: (path: string) => {},
|
||||
}
|
||||
}
|
||||
14
frontends/nextjs/src/hooks/useDBAL.ts
Normal file
14
frontends/nextjs/src/hooks/useDBAL.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* useDBAL hook (stub)
|
||||
*/
|
||||
|
||||
export function useDBAL() {
|
||||
// TODO: Implement useDBAL
|
||||
return {
|
||||
get: async (entity: string, id: string) => null,
|
||||
list: async (entity: string) => [],
|
||||
create: async (entity: string, data: unknown) => {},
|
||||
update: async (entity: string, id: string, data: unknown) => {},
|
||||
delete: async (entity: string, id: string) => {},
|
||||
}
|
||||
}
|
||||
20
frontends/nextjs/src/hooks/useFileTree.ts
Normal file
20
frontends/nextjs/src/hooks/useFileTree.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* useFileTree hook (stub)
|
||||
*/
|
||||
|
||||
export interface FileNode {
|
||||
name: string
|
||||
path: string
|
||||
type: 'file' | 'directory'
|
||||
children?: FileNode[]
|
||||
}
|
||||
|
||||
export function useFileTree(rootPath?: string) {
|
||||
// TODO: Implement useFileTree
|
||||
return {
|
||||
tree: null as FileNode | null,
|
||||
loading: false,
|
||||
error: null as Error | null,
|
||||
refresh: () => {},
|
||||
}
|
||||
}
|
||||
21
frontends/nextjs/src/hooks/useGitHubFetcher.ts
Normal file
21
frontends/nextjs/src/hooks/useGitHubFetcher.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* useGitHubFetcher hook (stub)
|
||||
*/
|
||||
|
||||
export interface WorkflowRun {
|
||||
id: number
|
||||
name: string
|
||||
status: string
|
||||
conclusion?: string
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
export function useGitHubFetcher() {
|
||||
// TODO: Implement useGitHubFetcher
|
||||
return {
|
||||
runs: [] as WorkflowRun[],
|
||||
loading: false,
|
||||
error: null as Error | null,
|
||||
refetch: () => {},
|
||||
}
|
||||
}
|
||||
13
frontends/nextjs/src/hooks/useKV.ts
Normal file
13
frontends/nextjs/src/hooks/useKV.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* useKV hook (stub)
|
||||
*/
|
||||
|
||||
export function useKV(namespace?: string) {
|
||||
// TODO: Implement useKV
|
||||
return {
|
||||
get: async (key: string) => null,
|
||||
set: async (key: string, value: unknown) => {},
|
||||
delete: async (key: string) => {},
|
||||
list: async (prefix?: string) => [],
|
||||
}
|
||||
}
|
||||
8
frontends/nextjs/src/lib/api/read-json.ts
Normal file
8
frontends/nextjs/src/lib/api/read-json.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Read JSON from request (stub)
|
||||
*/
|
||||
|
||||
export async function readJson<T = unknown>(request: Request): Promise<T> {
|
||||
// TODO: Implement JSON reading with validation
|
||||
return await request.json() as T
|
||||
}
|
||||
15
frontends/nextjs/src/lib/auth/api/fetch-session.ts
Normal file
15
frontends/nextjs/src/lib/auth/api/fetch-session.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Fetch current session (stub)
|
||||
*/
|
||||
|
||||
export interface Session {
|
||||
id: string
|
||||
userId: string
|
||||
token: string
|
||||
expiresAt: number
|
||||
}
|
||||
|
||||
export async function fetchSession(): Promise<Session | null> {
|
||||
// TODO: Implement session fetching
|
||||
return null
|
||||
}
|
||||
19
frontends/nextjs/src/lib/auth/api/login.ts
Normal file
19
frontends/nextjs/src/lib/auth/api/login.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Login API (stub)
|
||||
*/
|
||||
|
||||
export interface LoginCredentials {
|
||||
username: string
|
||||
password: string
|
||||
}
|
||||
|
||||
export interface LoginResponse {
|
||||
success: boolean
|
||||
token?: string
|
||||
error?: string
|
||||
}
|
||||
|
||||
export async function login(credentials: LoginCredentials): Promise<LoginResponse> {
|
||||
// TODO: Implement login
|
||||
return { success: false, error: 'Not implemented' }
|
||||
}
|
||||
7
frontends/nextjs/src/lib/auth/api/logout.ts
Normal file
7
frontends/nextjs/src/lib/auth/api/logout.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Logout API (stub)
|
||||
*/
|
||||
|
||||
export async function logout(): Promise<void> {
|
||||
// TODO: Implement logout
|
||||
}
|
||||
20
frontends/nextjs/src/lib/auth/api/register.ts
Normal file
20
frontends/nextjs/src/lib/auth/api/register.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Register API (stub)
|
||||
*/
|
||||
|
||||
export interface RegisterData {
|
||||
username: string
|
||||
email: string
|
||||
password: string
|
||||
}
|
||||
|
||||
export interface RegisterResponse {
|
||||
success: boolean
|
||||
userId?: string
|
||||
error?: string
|
||||
}
|
||||
|
||||
export async function register(data: RegisterData): Promise<RegisterResponse> {
|
||||
// TODO: Implement registration
|
||||
return { success: false, error: 'Not implemented' }
|
||||
}
|
||||
18
frontends/nextjs/src/lib/compiler/index.ts
Normal file
18
frontends/nextjs/src/lib/compiler/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Compiler utilities (stub)
|
||||
*/
|
||||
|
||||
export interface CompileOptions {
|
||||
minify?: boolean
|
||||
sourceMaps?: boolean
|
||||
}
|
||||
|
||||
export interface CompileResult {
|
||||
code: string
|
||||
map?: string
|
||||
}
|
||||
|
||||
export async function compile(source: string, options?: CompileOptions): Promise<CompileResult> {
|
||||
// TODO: Implement compilation
|
||||
return { code: source }
|
||||
}
|
||||
20
frontends/nextjs/src/lib/config/prisma.ts
Normal file
20
frontends/nextjs/src/lib/config/prisma.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Prisma Client singleton instance
|
||||
* Prevents multiple instances in development with hot reloading
|
||||
*/
|
||||
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
|
||||
const globalForPrisma = globalThis as unknown as {
|
||||
prisma: PrismaClient | undefined
|
||||
}
|
||||
|
||||
export const prisma =
|
||||
globalForPrisma.prisma ??
|
||||
new PrismaClient({
|
||||
log: process.env.NODE_ENV === 'development' ? ['error', 'warn'] : ['error'],
|
||||
})
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
globalForPrisma.prisma = prisma
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Get DBAL client instance (stub)
|
||||
*/
|
||||
|
||||
import { getAdapter } from '../../dbal-client/adapter/get-adapter'
|
||||
|
||||
export const getDBAL = getAdapter
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Initialize DBAL client (stub)
|
||||
*/
|
||||
|
||||
export async function initializeDBAL(): Promise<void> {
|
||||
// Stub: DBAL initialization handled by getAdapter
|
||||
console.log('DBAL initialized (Prisma adapter)')
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Add user via DBAL (stub)
|
||||
*/
|
||||
|
||||
import { getAdapter } from '../../dbal-client/adapter/get-adapter'
|
||||
import type { User } from '../../types/level-types'
|
||||
|
||||
export async function dbalAddUser(user: User): Promise<void> {
|
||||
const adapter = getAdapter()
|
||||
await adapter.create('User', user)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Delete user via DBAL (stub)
|
||||
*/
|
||||
|
||||
import { getAdapter } from '../../dbal-client/adapter/get-adapter'
|
||||
|
||||
export async function dbalDeleteUser(id: string): Promise<void> {
|
||||
const adapter = getAdapter()
|
||||
await adapter.delete('User', id)
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Get user by ID via DBAL (stub)
|
||||
*/
|
||||
|
||||
import { getAdapter } from '../../dbal-client/adapter/get-adapter'
|
||||
import type { User } from '../../types/level-types'
|
||||
|
||||
export async function dbalGetUserById(id: string): Promise<User | null> {
|
||||
const adapter = getAdapter()
|
||||
return await adapter.get('User', id) as User | null
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Get users via DBAL (stub)
|
||||
*/
|
||||
|
||||
import { getAdapter } from '../../dbal-client/adapter/get-adapter'
|
||||
import type { User } from '../../types/level-types'
|
||||
import type { ListOptions, ListResult } from '../../dbal-client/types'
|
||||
|
||||
export async function dbalGetUsers(options?: ListOptions): Promise<ListResult<User>> {
|
||||
const adapter = getAdapter()
|
||||
return await adapter.list('User', options) as ListResult<User>
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* Update user via DBAL (stub)
|
||||
*/
|
||||
|
||||
import { getAdapter } from '../../dbal-client/adapter/get-adapter'
|
||||
import type { User } from '../../types/level-types'
|
||||
|
||||
export async function dbalUpdateUser(id: string, data: Partial<User>): Promise<User> {
|
||||
const adapter = getAdapter()
|
||||
return await adapter.update('User', id, data) as User
|
||||
}
|
||||
18
frontends/nextjs/src/lib/db/password/index.ts
Normal file
18
frontends/nextjs/src/lib/db/password/index.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Password utilities and SMTP configuration types
|
||||
*/
|
||||
|
||||
export { hashPassword } from './hash-password'
|
||||
export { verifyPassword } from './verify-password'
|
||||
|
||||
// SMTP Configuration type
|
||||
export interface SMTPConfig {
|
||||
id?: string
|
||||
host: string
|
||||
port: number
|
||||
secure: boolean
|
||||
username: string
|
||||
password: string
|
||||
fromEmail: string
|
||||
fromName: string
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Close the DBAL adapter connection
|
||||
*/
|
||||
|
||||
import { getAdapter } from './get-adapter'
|
||||
|
||||
export async function closeAdapter(): Promise<void> {
|
||||
const adapter = getAdapter()
|
||||
await adapter.close()
|
||||
}
|
||||
123
frontends/nextjs/src/lib/dbal-client/adapter/get-adapter.ts
Normal file
123
frontends/nextjs/src/lib/dbal-client/adapter/get-adapter.ts
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Get the current DBAL adapter instance
|
||||
*/
|
||||
|
||||
import { prisma } from '../../config/prisma'
|
||||
import type { DBALAdapter, ListOptions, ListResult } from '../types'
|
||||
|
||||
// Simple Prisma-based adapter implementation
|
||||
class PrismaAdapter implements DBALAdapter {
|
||||
async create(entity: string, data: Record<string, unknown>): Promise<unknown> {
|
||||
const model = (prisma as any)[entity.toLowerCase()]
|
||||
if (!model) throw new Error(`Unknown entity: ${entity}`)
|
||||
return await model.create({ data })
|
||||
}
|
||||
|
||||
async get(entity: string, id: string | number): Promise<unknown> {
|
||||
const model = (prisma as any)[entity.toLowerCase()]
|
||||
if (!model) throw new Error(`Unknown entity: ${entity}`)
|
||||
return await model.findUnique({ where: { id } })
|
||||
}
|
||||
|
||||
async list(entity: string, options?: ListOptions): Promise<ListResult> {
|
||||
const model = (prisma as any)[entity.toLowerCase()]
|
||||
if (!model) throw new Error(`Unknown entity: ${entity}`)
|
||||
|
||||
const where = options?.filter || {}
|
||||
const orderBy = options?.orderBy ? { [options.orderBy]: options.orderDirection || 'asc' } : undefined
|
||||
|
||||
const [data, total] = await Promise.all([
|
||||
model.findMany({
|
||||
where,
|
||||
orderBy,
|
||||
take: options?.limit,
|
||||
skip: options?.offset,
|
||||
}),
|
||||
model.count({ where }),
|
||||
])
|
||||
|
||||
return {
|
||||
data,
|
||||
total,
|
||||
hasMore: options?.limit ? (options.offset || 0) + data.length < total : false,
|
||||
}
|
||||
}
|
||||
|
||||
async update(entity: string, id: string | number, data: Record<string, unknown>): Promise<unknown> {
|
||||
const model = (prisma as any)[entity.toLowerCase()]
|
||||
if (!model) throw new Error(`Unknown entity: ${entity}`)
|
||||
return await model.update({ where: { id }, data })
|
||||
}
|
||||
|
||||
async upsert(
|
||||
entity: string,
|
||||
uniqueField: string,
|
||||
uniqueValue: unknown,
|
||||
createData: Record<string, unknown>,
|
||||
updateData: Record<string, unknown>
|
||||
): Promise<unknown> {
|
||||
const model = (prisma as any)[entity.toLowerCase()]
|
||||
if (!model) throw new Error(`Unknown entity: ${entity}`)
|
||||
return await model.upsert({
|
||||
where: { [uniqueField]: uniqueValue },
|
||||
create: createData,
|
||||
update: updateData,
|
||||
})
|
||||
}
|
||||
|
||||
async delete(entity: string, id: string | number): Promise<void> {
|
||||
const model = (prisma as any)[entity.toLowerCase()]
|
||||
if (!model) throw new Error(`Unknown entity: ${entity}`)
|
||||
await model.delete({ where: { id } })
|
||||
}
|
||||
|
||||
async createMany(entity: string, data: Record<string, unknown>[]): Promise<unknown[]> {
|
||||
const model = (prisma as any)[entity.toLowerCase()]
|
||||
if (!model) throw new Error(`Unknown entity: ${entity}`)
|
||||
await model.createMany({ data })
|
||||
return data
|
||||
}
|
||||
|
||||
async updateMany(entity: string, ids: (string | number)[], data: Record<string, unknown>): Promise<unknown[]> {
|
||||
const model = (prisma as any)[entity.toLowerCase()]
|
||||
if (!model) throw new Error(`Unknown entity: ${entity}`)
|
||||
|
||||
const results = await Promise.all(
|
||||
ids.map(id => model.update({ where: { id }, data }))
|
||||
)
|
||||
return results
|
||||
}
|
||||
|
||||
async deleteMany(entity: string, ids: (string | number)[]): Promise<void> {
|
||||
const model = (prisma as any)[entity.toLowerCase()]
|
||||
if (!model) throw new Error(`Unknown entity: ${entity}`)
|
||||
await model.deleteMany({ where: { id: { in: ids } } })
|
||||
}
|
||||
|
||||
async query(entity: string, filter: Record<string, unknown>, options?: ListOptions): Promise<ListResult> {
|
||||
return this.list(entity, { ...options, filter })
|
||||
}
|
||||
|
||||
async count(entity: string, filter?: Record<string, unknown>): Promise<number> {
|
||||
const model = (prisma as any)[entity.toLowerCase()]
|
||||
if (!model) throw new Error(`Unknown entity: ${entity}`)
|
||||
return await model.count({ where: filter || {} })
|
||||
}
|
||||
|
||||
async transaction<T>(fn: (adapter: DBALAdapter) => Promise<T>): Promise<T> {
|
||||
return await prisma.$transaction(async () => fn(this))
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
await prisma.$disconnect()
|
||||
}
|
||||
}
|
||||
|
||||
let adapter: DBALAdapter | null = null
|
||||
|
||||
export function getAdapter(): DBALAdapter {
|
||||
if (!adapter) {
|
||||
adapter = new PrismaAdapter()
|
||||
}
|
||||
return adapter
|
||||
}
|
||||
54
frontends/nextjs/src/lib/dbal-client/types.ts
Normal file
54
frontends/nextjs/src/lib/dbal-client/types.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* DBAL Adapter types
|
||||
*/
|
||||
|
||||
export interface ListOptions {
|
||||
limit?: number
|
||||
offset?: number
|
||||
orderBy?: string
|
||||
orderDirection?: 'asc' | 'desc'
|
||||
filter?: Record<string, unknown>
|
||||
}
|
||||
|
||||
export interface ListResult<T = unknown> {
|
||||
data: T[]
|
||||
total: number
|
||||
hasMore: boolean
|
||||
}
|
||||
|
||||
export interface DBALAdapter {
|
||||
// Create operations
|
||||
create(entity: string, data: Record<string, unknown>): Promise<unknown>
|
||||
|
||||
// Read operations
|
||||
get(entity: string, id: string | number): Promise<unknown>
|
||||
list(entity: string, options?: ListOptions): Promise<ListResult>
|
||||
|
||||
// Update operations
|
||||
update(entity: string, id: string | number, data: Record<string, unknown>): Promise<unknown>
|
||||
upsert(
|
||||
entity: string,
|
||||
uniqueField: string,
|
||||
uniqueValue: unknown,
|
||||
createData: Record<string, unknown>,
|
||||
updateData: Record<string, unknown>
|
||||
): Promise<unknown>
|
||||
|
||||
// Delete operations
|
||||
delete(entity: string, id: string | number): Promise<void>
|
||||
|
||||
// Batch operations
|
||||
createMany(entity: string, data: Record<string, unknown>[]): Promise<unknown[]>
|
||||
updateMany(entity: string, ids: (string | number)[], data: Record<string, unknown>): Promise<unknown[]>
|
||||
deleteMany(entity: string, ids: (string | number)[]): Promise<void>
|
||||
|
||||
// Query operations
|
||||
query(entity: string, filter: Record<string, unknown>, options?: ListOptions): Promise<ListResult>
|
||||
count(entity: string, filter?: Record<string, unknown>): Promise<number>
|
||||
|
||||
// Transaction support
|
||||
transaction<T>(fn: (adapter: DBALAdapter) => Promise<T>): Promise<T>
|
||||
|
||||
// Lifecycle
|
||||
close(): Promise<void>
|
||||
}
|
||||
12
frontends/nextjs/src/lib/github/create-github-client.ts
Normal file
12
frontends/nextjs/src/lib/github/create-github-client.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Create GitHub client (stub)
|
||||
*/
|
||||
|
||||
export interface GitHubClient {
|
||||
// Add methods as needed
|
||||
}
|
||||
|
||||
export function createGitHubClient(token?: string): GitHubClient {
|
||||
// TODO: Implement GitHub client creation
|
||||
return {}
|
||||
}
|
||||
46
frontends/nextjs/src/lib/github/fetch-workflow-run-logs.ts
Normal file
46
frontends/nextjs/src/lib/github/fetch-workflow-run-logs.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Fetch workflow run logs (stub)
|
||||
*/
|
||||
|
||||
export interface WorkflowJob {
|
||||
id: number
|
||||
name: string
|
||||
status: string
|
||||
conclusion?: string
|
||||
}
|
||||
|
||||
export interface WorkflowRunLogs {
|
||||
logs: string
|
||||
runId: number
|
||||
jobs?: WorkflowJob[]
|
||||
logsText?: string
|
||||
truncated?: boolean
|
||||
}
|
||||
|
||||
export interface FetchWorkflowRunLogsOptions {
|
||||
client?: unknown
|
||||
owner: string
|
||||
repo: string
|
||||
runId: number
|
||||
tailLines?: number
|
||||
failedOnly?: boolean
|
||||
}
|
||||
|
||||
export async function fetchWorkflowRunLogs(
|
||||
options: FetchWorkflowRunLogsOptions
|
||||
): Promise<WorkflowRunLogs | null>
|
||||
export async function fetchWorkflowRunLogs(
|
||||
owner: string,
|
||||
repo: string,
|
||||
runId: number,
|
||||
options?: { tailLines?: number; failedOnly?: boolean }
|
||||
): Promise<WorkflowRunLogs | null>
|
||||
export async function fetchWorkflowRunLogs(
|
||||
ownerOrOptions: string | FetchWorkflowRunLogsOptions,
|
||||
repo?: string,
|
||||
runId?: number,
|
||||
options?: { tailLines?: number; failedOnly?: boolean }
|
||||
): Promise<WorkflowRunLogs | null> {
|
||||
// TODO: Implement log fetching
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Parse workflow run logs options (stub)
|
||||
*/
|
||||
|
||||
export interface WorkflowRunLogsOptions {
|
||||
tailLines?: number
|
||||
failedOnly?: boolean
|
||||
runName?: string
|
||||
includeLogs?: boolean
|
||||
jobLimit?: number
|
||||
}
|
||||
|
||||
export function parseWorkflowRunLogsOptions(search: string | URLSearchParams): WorkflowRunLogsOptions {
|
||||
// TODO: Implement option parsing
|
||||
const params = typeof search === 'string' ? new URLSearchParams(search) : search
|
||||
return {
|
||||
tailLines: params.get('tailLines') ? parseInt(params.get('tailLines')!) : undefined,
|
||||
failedOnly: params.get('failedOnly') === 'true',
|
||||
runName: params.get('runName') || undefined,
|
||||
includeLogs: params.get('includeLogs') === 'true',
|
||||
jobLimit: params.get('jobLimit') ? parseInt(params.get('jobLimit')!) : undefined,
|
||||
}
|
||||
}
|
||||
21
frontends/nextjs/src/lib/github/resolve-github-repo.ts
Normal file
21
frontends/nextjs/src/lib/github/resolve-github-repo.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Resolve GitHub repository (stub)
|
||||
*/
|
||||
|
||||
export interface GitHubRepo {
|
||||
owner: string
|
||||
repo: string
|
||||
}
|
||||
|
||||
export function resolveGitHubRepo(params: URLSearchParams | string): GitHubRepo {
|
||||
// TODO: Implement repo resolution
|
||||
if (typeof params === 'string') {
|
||||
const [owner, repo] = params.split('/')
|
||||
return { owner: owner || '', repo: repo || '' }
|
||||
}
|
||||
|
||||
return {
|
||||
owner: params.get('owner') || '',
|
||||
repo: params.get('repo') || '',
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* List workflow runs (stub)
|
||||
*/
|
||||
|
||||
export interface WorkflowRun {
|
||||
id: number
|
||||
name: string
|
||||
status: string
|
||||
conclusion?: string
|
||||
createdAt: string
|
||||
}
|
||||
|
||||
export async function listWorkflowRuns(
|
||||
owner: string,
|
||||
repo: string,
|
||||
search?: string,
|
||||
workflowId?: string
|
||||
): Promise<WorkflowRun[]> {
|
||||
// TODO: Implement workflow runs listing
|
||||
return []
|
||||
}
|
||||
14
frontends/nextjs/src/lib/lua/ui/generate-component-tree.ts
Normal file
14
frontends/nextjs/src/lib/lua/ui/generate-component-tree.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Generate component tree from Lua (stub)
|
||||
*/
|
||||
|
||||
export interface ComponentTree {
|
||||
type: string
|
||||
props?: Record<string, unknown>
|
||||
children?: ComponentTree[]
|
||||
}
|
||||
|
||||
export function generateComponentTree(luaScript: string): ComponentTree {
|
||||
// TODO: Implement Lua component tree generation
|
||||
return { type: 'div' }
|
||||
}
|
||||
9
frontends/nextjs/src/lib/lua/ui/types/lua-ui-package.ts
Normal file
9
frontends/nextjs/src/lib/lua/ui/types/lua-ui-package.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Lua UI types (stub)
|
||||
*/
|
||||
|
||||
export interface LuaUIPackage {
|
||||
id: string
|
||||
name: string
|
||||
components: unknown[]
|
||||
}
|
||||
6
frontends/nextjs/src/lib/package-lib/package-export.ts
Normal file
6
frontends/nextjs/src/lib/package-lib/package-export.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Package export utilities
|
||||
* Re-exports from packages module
|
||||
*/
|
||||
|
||||
export * from '../packages'
|
||||
14
frontends/nextjs/src/lib/packages/json/load-json-package.ts
Normal file
14
frontends/nextjs/src/lib/packages/json/load-json-package.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Load JSON package (stub)
|
||||
*/
|
||||
|
||||
export interface JSONPackage {
|
||||
id: string
|
||||
components: unknown[]
|
||||
metadata: unknown
|
||||
}
|
||||
|
||||
export async function loadJSONPackage(packageId: string): Promise<JSONPackage | null> {
|
||||
// TODO: Implement JSON package loading
|
||||
return null
|
||||
}
|
||||
@@ -30,3 +30,16 @@ export {
|
||||
getPackageScripts,
|
||||
getPackagesByCategory,
|
||||
} from './functions'
|
||||
|
||||
// Package glue singleton (stub)
|
||||
export const packageGlue = {
|
||||
getPackage,
|
||||
getPackageComponents,
|
||||
getPackageScripts,
|
||||
getPackagesByCategory,
|
||||
checkDependencies,
|
||||
}
|
||||
|
||||
export function getPackageGlue() {
|
||||
return packageGlue
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Validate package route (stub)
|
||||
*/
|
||||
|
||||
export interface RouteValidationResult {
|
||||
valid: boolean
|
||||
error?: string
|
||||
}
|
||||
|
||||
export async function validatePackageRoute(
|
||||
tenant: string,
|
||||
packageId: string,
|
||||
userId?: string
|
||||
): Promise<RouteValidationResult> {
|
||||
// TODO: Implement route validation
|
||||
return { valid: true }
|
||||
}
|
||||
|
||||
export async function canBePrimaryPackage(packageId: string): Promise<boolean> {
|
||||
// TODO: Implement primary package check
|
||||
return true
|
||||
}
|
||||
|
||||
export async function loadPackageMetadata(packageId: string): Promise<unknown> {
|
||||
// TODO: Implement package metadata loading
|
||||
return null
|
||||
}
|
||||
13
frontends/nextjs/src/lib/routing/index.ts
Normal file
13
frontends/nextjs/src/lib/routing/index.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Routing utilities (stub)
|
||||
*/
|
||||
|
||||
export function parseRoute(path: string): Record<string, string> {
|
||||
// TODO: Implement route parsing
|
||||
return {}
|
||||
}
|
||||
|
||||
export function buildRoute(template: string, params: Record<string, string>): string {
|
||||
// TODO: Implement route building
|
||||
return template
|
||||
}
|
||||
32
frontends/nextjs/src/lib/routing/route-parser.ts
Normal file
32
frontends/nextjs/src/lib/routing/route-parser.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Route parser (stub)
|
||||
*/
|
||||
|
||||
export interface ParsedRoute {
|
||||
tenant?: string
|
||||
package?: string
|
||||
path?: string
|
||||
params: Record<string, string>
|
||||
}
|
||||
|
||||
export const RESERVED_PATHS = ['api', 'admin', 'auth', '_next', 'static']
|
||||
|
||||
export function parseRoute(url: string): ParsedRoute {
|
||||
// TODO: Implement route parsing
|
||||
return { params: {} }
|
||||
}
|
||||
|
||||
export function getPrefixedEntity(entity: string, prefix?: string): string {
|
||||
// TODO: Implement entity prefixing
|
||||
return prefix ? `${prefix}_${entity}` : entity
|
||||
}
|
||||
|
||||
export function getTableName(entity: string, tenantId?: string): string {
|
||||
// TODO: Implement table name resolution
|
||||
return entity.toLowerCase()
|
||||
}
|
||||
|
||||
export function isReservedPath(path: string): boolean {
|
||||
// TODO: Implement reserved path checking
|
||||
return RESERVED_PATHS.includes(path.split('/')[1] || path)
|
||||
}
|
||||
6
frontends/nextjs/src/lib/schema/index.ts
Normal file
6
frontends/nextjs/src/lib/schema/index.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Schema utilities and operations
|
||||
* Re-exports from db/schemas module
|
||||
*/
|
||||
|
||||
export * from '../db/schemas'
|
||||
59
frontends/nextjs/src/lib/schema/schema-registry.ts
Normal file
59
frontends/nextjs/src/lib/schema/schema-registry.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Schema registry (stub)
|
||||
*/
|
||||
|
||||
import type { ModelSchema } from '../types/schema-types'
|
||||
|
||||
export class SchemaRegistry {
|
||||
private schemas: Map<string, ModelSchema> = new Map()
|
||||
packages: Record<string, unknown> = {}
|
||||
|
||||
register(schema: ModelSchema): void {
|
||||
this.schemas.set(schema.name, schema)
|
||||
}
|
||||
|
||||
get(name: string): ModelSchema | undefined {
|
||||
return this.schemas.get(name)
|
||||
}
|
||||
|
||||
getAll(): ModelSchema[] {
|
||||
return Array.from(this.schemas.values())
|
||||
}
|
||||
}
|
||||
|
||||
export const schemaRegistry = new SchemaRegistry()
|
||||
|
||||
export function loadSchemaRegistry(path?: string): SchemaRegistry {
|
||||
// TODO: Implement schema registry loading
|
||||
return schemaRegistry
|
||||
}
|
||||
|
||||
export function saveSchemaRegistry(registry: SchemaRegistry, path?: string): void {
|
||||
// TODO: Implement schema registry saving
|
||||
}
|
||||
|
||||
export interface PendingMigration {
|
||||
id: string
|
||||
packageId: string
|
||||
status: string
|
||||
queuedAt: string
|
||||
entities: Array<{ name: string }>
|
||||
}
|
||||
|
||||
export function getPendingMigrations(registry: SchemaRegistry): PendingMigration[] {
|
||||
// TODO: Implement pending migrations retrieval
|
||||
return []
|
||||
}
|
||||
|
||||
export function generatePrismaFragment(schema: ModelSchema, path?: string): string {
|
||||
// TODO: Implement Prisma fragment generation
|
||||
return ''
|
||||
}
|
||||
|
||||
export function approveMigration(registry: SchemaRegistry, migrationId: string): void {
|
||||
// TODO: Implement migration approval
|
||||
}
|
||||
|
||||
export function rejectMigration(registry: SchemaRegistry, migrationId: string): void {
|
||||
// TODO: Implement migration rejection
|
||||
}
|
||||
10
frontends/nextjs/src/lib/seed/index.ts
Normal file
10
frontends/nextjs/src/lib/seed/index.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Seed data and database initialization utilities
|
||||
* Re-exports from database-admin module
|
||||
*/
|
||||
|
||||
// Export seed functionality from database-admin
|
||||
// This is a placeholder - actual implementation in db/database-admin
|
||||
export const seedDefaultData = async () => {
|
||||
console.warn('seedDefaultData: Not yet implemented')
|
||||
}
|
||||
75
frontends/nextjs/src/lib/types/level-types.ts
Normal file
75
frontends/nextjs/src/lib/types/level-types.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Type definitions for core database entities
|
||||
* These types match the Prisma schema models
|
||||
*/
|
||||
|
||||
export type UserRole = 'public' | 'user' | 'moderator' | 'admin' | 'god' | 'supergod'
|
||||
|
||||
export interface User {
|
||||
id: string
|
||||
username: string
|
||||
email: string
|
||||
role: string
|
||||
profilePicture?: string | null
|
||||
bio?: string | null
|
||||
createdAt: number | bigint
|
||||
tenantId?: string | null
|
||||
isInstanceOwner?: boolean
|
||||
passwordChangeTimestamp?: number | bigint | null
|
||||
firstLogin?: boolean
|
||||
}
|
||||
|
||||
export interface Tenant {
|
||||
id: string
|
||||
name: string
|
||||
slug: string
|
||||
ownerId: string
|
||||
createdAt: number | bigint
|
||||
homepageConfig?: string | null
|
||||
settings?: string | null
|
||||
}
|
||||
|
||||
export interface PageConfig {
|
||||
id: string
|
||||
tenantId?: string | null
|
||||
packageId?: string | null
|
||||
path: string
|
||||
title: string
|
||||
description?: string | null
|
||||
icon?: string | null
|
||||
component?: string | null
|
||||
luaScript?: string | null
|
||||
accessLevel?: number | null
|
||||
createdAt?: number | bigint
|
||||
updatedAt?: number | bigint
|
||||
}
|
||||
|
||||
export interface Comment {
|
||||
id: string
|
||||
userId: string
|
||||
entityType: string
|
||||
entityId: string
|
||||
content: string
|
||||
createdAt: number | bigint
|
||||
updatedAt?: number | bigint | null
|
||||
parentId?: string | null
|
||||
}
|
||||
|
||||
export interface Workflow {
|
||||
id: string
|
||||
name: string
|
||||
tenantId?: string | null
|
||||
definition: string
|
||||
status: string
|
||||
createdAt: number | bigint
|
||||
updatedAt?: number | bigint | null
|
||||
}
|
||||
|
||||
export interface AppConfiguration {
|
||||
id: string
|
||||
key: string
|
||||
value: string
|
||||
description?: string | null
|
||||
createdAt?: number | bigint
|
||||
updatedAt?: number | bigint | null
|
||||
}
|
||||
19
frontends/nextjs/src/lib/types/schema-types.ts
Normal file
19
frontends/nextjs/src/lib/types/schema-types.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Type definitions for schema-related entities
|
||||
*/
|
||||
|
||||
export interface ModelSchema {
|
||||
id: string
|
||||
tenantId?: string | null
|
||||
name: string
|
||||
label?: string | null
|
||||
labelPlural?: string | null
|
||||
icon?: string | null
|
||||
fields: string // JSON: field definitions
|
||||
listDisplay?: string | null // JSON: columns to show in list
|
||||
listFilter?: string | null // JSON: filterable fields
|
||||
searchFields?: string | null // JSON: searchable fields
|
||||
ordering?: string | null // JSON: default sort order
|
||||
validations?: string | null // JSON: validation rules
|
||||
hooks?: string | null // JSON: lifecycle hooks (Lua script refs)
|
||||
}
|
||||
10
frontends/nextjs/src/lib/ui-pages/load-page-from-db.ts
Normal file
10
frontends/nextjs/src/lib/ui-pages/load-page-from-db.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Load UI page from database (stub)
|
||||
*/
|
||||
|
||||
import type { PageConfig } from '../types/level-types'
|
||||
|
||||
export async function loadPageFromDb(path: string, tenantId?: string): Promise<PageConfig | null> {
|
||||
// TODO: Implement page loading from database
|
||||
return null
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Load UI page from Lua packages (stub)
|
||||
*/
|
||||
|
||||
import type { PageConfig } from '../types/level-types'
|
||||
|
||||
export async function loadPageFromLuaPackages(path: string): Promise<PageConfig | null> {
|
||||
// TODO: Implement page loading from Lua packages
|
||||
return null
|
||||
}
|
||||
@@ -60,10 +60,10 @@
|
||||
"vitest.config.ts",
|
||||
"playwright.config.ts",
|
||||
".next/types/**/*.ts",
|
||||
".next/dev/types/**/*.ts",
|
||||
"../dbal/development/src/**/*.ts"
|
||||
".next/dev/types/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
"node_modules",
|
||||
"../../dbal/development"
|
||||
]
|
||||
}
|
||||
|
||||
12
packages/admin_dialog/seed/metadata.json
Normal file
12
packages/admin_dialog/seed/metadata.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"packageId": "'$pkg'",
|
||||
"name": "'$(echo $pkg | sed 's/_/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')'",
|
||||
"version": "0.1.0",
|
||||
"description": "Package '$pkg'",
|
||||
"author": "MetaBuilder Team",
|
||||
"category": "ui",
|
||||
"exports": {
|
||||
"components": []
|
||||
},
|
||||
"dependencies": []
|
||||
}
|
||||
12
packages/dashboard/seed/metadata.json
Normal file
12
packages/dashboard/seed/metadata.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"packageId": "'$pkg'",
|
||||
"name": "'$(echo $pkg | sed 's/_/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')'",
|
||||
"version": "0.1.0",
|
||||
"description": "Package '$pkg'",
|
||||
"author": "MetaBuilder Team",
|
||||
"category": "ui",
|
||||
"exports": {
|
||||
"components": []
|
||||
},
|
||||
"dependencies": []
|
||||
}
|
||||
12
packages/data_table/seed/metadata.json
Normal file
12
packages/data_table/seed/metadata.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"packageId": "'$pkg'",
|
||||
"name": "'$(echo $pkg | sed 's/_/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')'",
|
||||
"version": "0.1.0",
|
||||
"description": "Package '$pkg'",
|
||||
"author": "MetaBuilder Team",
|
||||
"category": "ui",
|
||||
"exports": {
|
||||
"components": []
|
||||
},
|
||||
"dependencies": []
|
||||
}
|
||||
12
packages/form_builder/seed/metadata.json
Normal file
12
packages/form_builder/seed/metadata.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"packageId": "'$pkg'",
|
||||
"name": "'$(echo $pkg | sed 's/_/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')'",
|
||||
"version": "0.1.0",
|
||||
"description": "Package '$pkg'",
|
||||
"author": "MetaBuilder Team",
|
||||
"category": "ui",
|
||||
"exports": {
|
||||
"components": []
|
||||
},
|
||||
"dependencies": []
|
||||
}
|
||||
12
packages/nav_menu/seed/metadata.json
Normal file
12
packages/nav_menu/seed/metadata.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"packageId": "'$pkg'",
|
||||
"name": "'$(echo $pkg | sed 's/_/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')'",
|
||||
"version": "0.1.0",
|
||||
"description": "Package '$pkg'",
|
||||
"author": "MetaBuilder Team",
|
||||
"category": "ui",
|
||||
"exports": {
|
||||
"components": []
|
||||
},
|
||||
"dependencies": []
|
||||
}
|
||||
12
packages/notification_center/seed/metadata.json
Normal file
12
packages/notification_center/seed/metadata.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"packageId": "'$pkg'",
|
||||
"name": "'$(echo $pkg | sed 's/_/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')'",
|
||||
"version": "0.1.0",
|
||||
"description": "Package '$pkg'",
|
||||
"author": "MetaBuilder Team",
|
||||
"category": "ui",
|
||||
"exports": {
|
||||
"components": []
|
||||
},
|
||||
"dependencies": []
|
||||
}
|
||||
12
packages/ui_dialogs/seed/metadata.json
Normal file
12
packages/ui_dialogs/seed/metadata.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"packageId": "'$pkg'",
|
||||
"name": "'$(echo $pkg | sed 's/_/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')'",
|
||||
"version": "0.1.0",
|
||||
"description": "Package '$pkg'",
|
||||
"author": "MetaBuilder Team",
|
||||
"category": "ui",
|
||||
"exports": {
|
||||
"components": []
|
||||
},
|
||||
"dependencies": []
|
||||
}
|
||||
12
packages/ui_permissions/seed/metadata.json
Normal file
12
packages/ui_permissions/seed/metadata.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"packageId": "'$pkg'",
|
||||
"name": "'$(echo $pkg | sed 's/_/ /g' | awk '{for(i=1;i<=NF;i++)sub(/./,toupper(substr($i,1,1)),$i)}1')'",
|
||||
"version": "0.1.0",
|
||||
"description": "Package '$pkg'",
|
||||
"author": "MetaBuilder Team",
|
||||
"category": "ui",
|
||||
"exports": {
|
||||
"components": []
|
||||
},
|
||||
"dependencies": []
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
"@types/react-dom": "^18.3.5",
|
||||
"@vitejs/plugin-react": "^4.5.2",
|
||||
"sass": "^1.97.1",
|
||||
"storybook": "^8.6.15",
|
||||
"storybook": "^10.1.11",
|
||||
"typescript": "^5.9.3",
|
||||
"vite": "^6.3.5"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user